JBoss 7、Hibernate をデフォルトの JPA 実装として、JSF を Web フロントエンドとして使用する Seam 3 サンドボックス アプリケーションがあります。
SQL UPDATE がデフォルトで飲み込まれてしまうという問題があります。
会話スコープのステートフル EJB は、拡張スコープの EntityManager と 1 つのエンティティ、コンテナー管理トランザクションを維持します (新規が必要)
- EntityManager が注入される
- EJB は EM を使用してエンティティをロードし、それをフィールドに保持します。
- JSF アプリケーションは EJB とそのエンティティにアクセスし、文字列フィールドを変更します
- JSF アプリケーションが EJB の「Save」メソッドを呼び出す
- save() で、エンティティフィールドが変更されたかどうかを確認します->適切に変更されました
- save() が終了した後、コンテナーはトランザクションをコミットします。
- 問題: DB に対して SQL 更新が実行されません。
save() を次のように拡張すると:
a) entityManager.contains(entity) UPDATE が期待どおりに実行される (結果は「true」)
また
b) entityManager.persist(entity) UPDATE が期待どおりに実行される
Q: 私が理解している限りでは、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";
}
}