我有一个Seam 3沙箱应用程序,它使用JBoss 7,Hibernate作为默认的JPA实现,JSF作为Web前端。JPA/Hibernate在EJB/Seam环境下不提交UPDATE提交更新
我有问题,SQL UPDATE被默认吞下。
我在谈话范围状态EJB维持一个扩展范围的EntityManager的和一个实体,容器管理事务(需要新)
- 实体管理器被注入
- 的EJB使用EM加载实体并保持它在一个场
- JSF应用访问EJB及其实体,改变字符串字段中EJB
- JSF应用卡列斯“保存”方法
- 在保存()我检查,如果实体字段已更改 - >它已被正确更改
- 我什么也没做,容器在save()完成后提交事务。
- 问题:没有对数据库执行SQL更新。
如果我延伸保存()由:
a)按预期执行UPDATE entityManager.contains(实体)(结果为 “真”)
OR
b)中entityManager.persist(entity)UPDATE按预期方式执行
问:据我了解规范不应该要求a)或b),因为实体在整个过程中保持管理状态。 我不明白,为什么a)对储蓄有影响。 我可以成像b)对储存有影响,但它不应该是必需的,应该吗?
欢迎任何解释。
这里是我的EJB:
@Named
@ConversationScoped
@Stateful
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class LanguageBean {
@PersistenceContext(type = PersistenceContextType.EXTENDED)
private EntityManager em;
@Inject
private UserTransaction transaction;
private Language value;
@Inject
Conversation conversation;
public LanguageBean() {
super();
}
@Begin
public void selectLanguage(Long anId) {
conversation.setTimeout(10 * 60 * 1000);
if (anId != null) {
value = em.find(Language.class, anId);
}
}
@BeforeCompletion
public void transactionComplete(){
System.out.println("transactionComplete");
}
public Language getValue() {
return value;
}
@Produces
@Named
@ConversationScoped
public Language getLanguage() {
return getValue();
}
public void setValue(Language aValue) {
value = aValue;
}
@End
public String save() {
// displays the changed attribute:
System.out.println("save code: "+value.getCode());
// why is either this required:
// boolean tempContains = em.contains(value);
// System.out.println("managed: "+tempContains);
// or: why is persist required:
em.persist(value);
return "languages?faces-redirect=true";
}
@End
public String cancel() throws SystemException {
transaction.setRollbackOnly();
return "languages?faces-redirect=true";
}
}
我发现entityManager.flush ()也解决了这个问题。但我不明白为什么这似乎是必需的。根据JPA规范:“当JTA事务提交时,提供者必须将所有修改后的实体状态刷新到 数据库。” – user1187037 2012-02-03 08:52:08
也许某处休眠会话的FlushMode设置为none? – Firo 2012-02-06 11:40:20