【发布时间】:2012-02-25 21:40:54
【问题描述】:
我有一个 Seam 3 沙盒应用程序,使用 JBoss 7,Hibernate 作为默认 JPA 实现,JSF 作为 Web 前端。
我有一个问题,SQL UPDATE 被默认吞下。
我在对话范围内的有状态 EJB 维护一个扩展范围的 EntityManager 和一个实体、容器管理事务(需要新的)
- EntityManager 被注入
- EJB 使用 EM 加载实体并将其保存在字段中
- JSF 应用程序访问 EJB 及其实体,更改字符串字段
- JSF 应用程序在 EJB 中调用“Save”方法
- 在 save() 中,我检查实体字段是否已更改 -> 是否已正确更改
- 我什么都不做,容器在 save() 完成后提交事务。
- 问题:没有对数据库执行 SQL 更新。
如果我将 save() 扩展为:
a) entityManager.contains(entity) UPDATE 按预期执行(结果为“true”)
或
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 事务提交时,提供者必须将所有修改的实体状态刷新到数据库。”
-
也许休眠会话的 FlushMode 设置为 none?
标签: hibernate ejb-3.0 jpa-2.0 seam3 jboss7.x