JBoss 7.1.1 Final、Weld、Hibernate 4、Seam 3 で開発していますが、次の動作がわかりません。Entity manager には Seam Managed Persistence Context を使用し、Seam 3 の Persistence Interceptor を使用しています。次の CDI Bean があります。
@ViewScoped
@Named
public class RegistrationController implements Serializable {
@Inject
private RegisterService service;
@Inject
private EntityManager em;
public void register() {
Person p = service.register("username","password");
Person pp = em.find(Person.class, p.getId()); //returns null
}
}
そして次のEJB
@Stateless
@Local(IRegisterService.class)
public RegisterService implements IRegisterService {
@Inject
private EntityManager em;
@Override
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public Person register(String username, String password) {
return em.merge(new Person(username, password));
}
}
Seam Persistence モジュールを使用しているため、次の操作の流れが発生すると想定しています。
1) registrationController.register() がフロントエンドから呼び出されます
2) 新しいトランザクション A が開始されます
3) service.register(...) が呼び出されます
4) トランザクション A が中断され、トランザクション B が service.register の実行用に作成されます (REQUIRES_NEW によってアノテーションが付けられているため)
5) service.register(...) の実行が完了する
6) トランザクション B がコミットされる
7) COMMIT フラッシュ タイプを使用しているため、フラッシュが呼び出されます。
8) トランザクション A が開かれます
現在、 em.find(Person.class, p.getId()) は永続化された人だけを見つけようとしています。トランザクション B がコミットされ、エンティティ マネージャーがフラッシュされたので、トランザクション B が見つかるはずです。しかし、それは null を返します。手動でフラッシュすると、機能します。
どこで間違いを犯していますか?何か誤解がありますか?