EclipseLink実装でJPAを使用する。
コード:
try{
if(!em.getTransaction().isActive())
em.getTransaction().begin();
System.out.println(2);
em.persist(currentUser);
System.out.println(3);
if (em.getTransaction().isActive()){
System.out.println("IS ACTIVE");
} else {
System.out.println("NO ACTIVE");
}
em.getTransaction().commit();
System.out.println(4);
} catch (Exception e){
completed = false;
em.getTransaction().rollback();
System.out.println("ERROR: " + e.getMessage());
}
エラー:
INFO: persistOne - Enter
INFO: 2
INFO: 3
INFO: IS ACTIVE
INFO: [EL Warning]: 2012-01-06 14:45:59.221--UnitOfWork(12492659)--Java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: com.maze.model.UserDetail@d52ea.
WARNING: #{accountController.performRegister}: Java.lang.IllegalStateException:
Exception Description: No transaction is currently active
javax.faces.FacesException: #{accountController.performRegister}: Java.lang.IllegalStateException:
Exception Description: No transaction is currently active
at com.Sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.Java:118)
at javax.faces.component.UICommand.broadcast(UICommand.Java:315)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.Java:794)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.Java:1259)
at com.Sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.Java:81)
at com.Sun.faces.lifecycle.Phase.doPhase(Phase.Java:101)
at com.Sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.Java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.Java:593)
at org.Apache.catalina.core.StandardWrapper.service(StandardWrapper.Java:1539)
at org.Apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.Java:281)
at org.Apache.catalina.core.StandardContextValve.invoke(StandardContextValve.Java:175)
at org.Apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.Java:655)
at org.Apache.catalina.core.StandardPipeline.invoke(StandardPipeline.Java:595)
at com.Sun.enterprise.web.WebPipeline.invoke(WebPipeline.Java:98)
at com.Sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.Java:91)
at org.Apache.catalina.core.StandardHostValve.invoke(StandardHostValve.Java:162)
at org.Apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.Java:330)
at org.Apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.Java:231)
at com.Sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.Java:174)
at com.Sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.Java:828)
at com.Sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.Java:725)
at com.Sun.grizzly.http.ProcessorTask.process(ProcessorTask.Java:1019)
at com.Sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.Java:225)
at com.Sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.Java:137)
at com.Sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.Java:104)
at com.Sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.Java:90)
at com.Sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.Java:79)
at com.Sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.Java:54)
at com.Sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.Java:59)
at com.Sun.grizzly.ContextTask.run(ContextTask.Java:71)
at com.Sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.Java:532)
at com.Sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.Java:513)
at Java.lang.Thread.run(Thread.Java:662)
Caused by: javax.faces.el.EvaluationException: Java.lang.IllegalStateException:
Exception Description: No transaction is currently active
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.Java:102)
at com.Sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.Java:102)
... 32 more
Caused by: Java.lang.IllegalStateException:
Exception Description: No transaction is currently active
at org.Eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.rollback(EntityTransactionImpl.Java:122)
at com.maze.service.UserService.persistOne(UserService.Java:63)
at com.maze.controller.request.AccountController.performRegister(AccountController.Java:62)
at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:39)
at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:25)
at Java.lang.reflect.Method.invoke(Method.Java:597)
at com.Sun.el.parser.AstValue.invoke(AstValue.Java:234)
at com.Sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.Java:297)
at com.Sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.Java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.Java:88)
... 33 more
奇妙なことに、トランザクションはアクティブですが、次に発生するのは非アクティブのエラーです。
[〜#〜] edit [〜#〜]EntityManager Singleton:public class EntityManagerSingleton {
private EntityManagerSingleton(){
}
private static class EMSingletonHolder{
private static final EntityManagerFactory emf = Persistence.createEntityManagerFactory("Maze");
private static final EntityManager em = emf.createEntityManager();
}
public static EntityManager getInstance(){
return EMSingletonHolder.em;
}
* emインスタンスの取得:*
public abstract class AbstractService {
protected EntityManager em;
public AbstractService(){
em = EntityManagerSingleton.getInstance();
}
}
他のすべてのサービスはAbstractServiceを拡張します
ログから判断すると、GlassFishを使用しています。あなたもJTAを使用していると思います。 EntityManagerインスタンスを取得するコードも提供できますか?また、System.outステートメントを使用したデバッグは過去のものであり、デバッガーを使用してください。そうしないと、コードが読みにくくなります。さらに、インデントが間違っています。
まず、JTAを使用している場合は、次の質問をご覧ください。
entityManager.getTransaction()を呼び出すときのEJBBException
受け入れられた回答からの引用:
Java EE管理コンテキストでEntityManagerに関連付けられたEntityTransactionインスタンスへの参照を取得することは不正です。 Java EntityManager.getTransaction()のEE APIドキュメント:
リソースレベルのEntityTransactionオブジェクトを返します。 EntityTransactionインスタンスを連続して使用して、複数のトランザクションを開始およびコミットできます。
Returns:
EntityTransaction instance Throws:
IllegalStateException - if invoked on a JTA entity manager
そのため、何らかの助けが必要な場合は、エンティティマネージャーを取得するためのコード/インジェクションに関する情報を提供することが重要です。
また、コードを読みやすくするために、em.getTransaction()を複数回呼び出すことはできません。最初の呼び出しをTransactionオブジェクトに割り当てて、次のように再利用する必要があります。
//GOOD cause readable
EntityTransaction tx = em.getTransaction();
tx.begin();
em.persist(someObject);
tx.commit();
ではなく
//BAD cause hard to read
em.getTransaction().begin();
em.persist(someObject);
em.getTransaction().commit(); //NO!
最後の例外は、catchブロックのrollback()
によってスローされることに注意してください。
したがって、commit()
は次の例外をスローします。
Java.lang.IllegalStateException:同期中に、カスケードPERSIST:com.maze.model.UserDetail@d52eaとマークされていない関係を通じて新しいオブジェクトが見つかりました。
その例外は暗黙的なロールバックを引き起こすため、catchブロックの手動のrollback()
は、非アクティブなトランザクションが原因で別の例外をスローします。
信頼できる手動クリーンアップを行うには、catchブロックでもrollback()
を呼び出す前に、トランザクションがアクティブかどうかを確認する必要があります。
まあ、あなたのログは、コミット中にEclipselinkが例外を受け取り、トランザクションをロールバックしたことを説明しています。そのため、トランザクションはアクティブではなくなりました。
情報:[EL警告]:2012-01-06 14:45:59.221--UnitOfWork(12492659)-Java.lang.IllegalStateException:同期中に、カスケードPERSIST:comとマークされていない関係を通じて新しいオブジェクトが見つかりました。 maze.model.UserDetail@d52ea。
これらのスタックトレースの最後を見ると、
at org.Eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.rollback(EntityTransactionImpl.Java:122)
コミット中ではなく、ロールバック中のエラーです。これが非永続オブジェクトに関する警告に関連しているかどうか疑問に思っています。コミットの最後で何かがうまくいかず、フレームワークが遅すぎる時点でロールバックを試みます。そのUserDetail
オブジェクトを正しく登録すれば、問題は解決するでしょう。