EntityManager.flush()不立即刷新?

时间:2013-01-10 13:20:37

标签: java java-ee exception jpa ejb

我在EJB中有这个代码:

try{
    em.persist(joueur);
    em.persist(p);
    em.persist(astre);
    em.persist(planet);
    em.flush();         
}catch(Exception e){    
       logger.log(Level.FATAL, "test");
    // ExceptionManager.manageExceptions(e);             
}

此代码必须抛出异常,因为我已经触发(通过PostGreQSL)检查某些约束,并使用测试值来启动触发器。

我有一个奇怪的结果,因为我的日志显示test所以我进入catch块但我的代码没有捕获“全部”或“完整”异常,因为我的服务器日志显示所有异常堆栈而且我不知道知道为什么......看起来这个代码在...之后抛出异常。

我知道我必须调用flush()方法立即将实体存储到我的数据库中,但看起来它在这里不起作用,并且异常仍然传播到我的代码中。

几周以前这段代码有效但是我已经在另一个项目方面工作了,现在看来我有某种回归,我不知道为什么......

所以我的问题是这个问题:EntityManager.flush() 总是立即执行持续操作吗?

编辑:这是我的日志(稍微过时)(第一个> GF日志,第二个> Log4j个人日志): 对不起,它是法语版,但异常名称保持不变;)

[#|2013-01-10T15:03:28.218+0100|WARNING|glassfish3.1.2|org.eclipse.persistence.session.file:/E:/softs/serveurs/glassfish3_1122/glassfish/domains/domain1/applications/ear-0.0.1-SNAPSHOT/lib/entities-0.0.1-SNAPSHOT.jar_01|_ThreadID=72;_ThreadName=Thread-2;|Local 

Exception Stack: 
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): 



  org.eclipse.persistence.exceptions.DatabaseException
    Internal Exception: org.postgresql.util.PSQLException: ERREUR: le pseudo est déjà pris (player_name)=(hghghghggg)
    Error Code: 0
Call: INSERT INTO pretoria.pseudos (ID, CHANGEMENT, PSEUDO, VERSION, joueur_id) VALUES (?, ?, ?, ?, ?)
    bind => [5 parameters bound]
Query: InsertObjectQuery(com.sim.entities.Pseudo@190c460)
    at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:333)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.processExceptionForCommError(DatabaseAccessor.java:1494)
    ................
Caused by: org.postgresql.util.PSQLException: ERREUR: le pseudo est déjà pris (player_name)=(hghghghggg)
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2102)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1835)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
    ................
|#]

[#|2013-01-10T15:03:28.218+0100|WARNING|glassfish3.1.2|org.eclipse.persistence.session.file:/E:/softs/serveurs/glassfish3_1122/glassfish/domains/domain1/applications/ear-0.0.1-SNAPSHOT/lib/entities-0.0.1-SNAPSHOT.jar_01|_ThreadID=72;_ThreadName=Thread-2;|Local Exception Stack: 
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERREUR: la transaction est annulée, les commandes sont ignorées jusqu'à la fin du bloc
de la transaction
Error Code: 0
Call: INSERT INTO pretoria.joueurs (ID, BLOQUE, cle_validation, creation, EMAIL, LANGAGE, maj_temperament, NEWSLETTER, PASSWORD, POUSSIERE, SEL, TEMPERAMENT, VACANCES, VERSION, alliance_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    bind => [15 parameters bound]
Query: InsertObjectQuery(com.sim.entities.Joueur@1a21ad9)
    at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:333)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.processExceptionForCommError(DatabaseAccessor.java:1494)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:838)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:906)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:592)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:535)
    at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:1717)
    ................
Caused by: org.postgresql.util.PSQLException: ERREUR: la transaction est annulée, les commandes sont ignorées jusqu'à la fin du bloc
de la transaction
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2102)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1835)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:500)
    ................
|#]

[#|2013-01-10T15:03:28.234+0100|WARNING|glassfish3.1.2|org.eclipse.persistence.session.file:/E:/softs/serveurs/glassfish3_1122/glassfish/domains/domain1/applications/ear-0.0.1-SNAPSHOT/lib/entities-0.0.1-SNAPSHOT.jar_01.transaction|_ThreadID=72;_ThreadName=Thread-2;|Local Exception Stack: 
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERREUR: la transaction est annulée, les commandes sont ignorées jusqu'à la fin du bloc
de la transaction
Error Code: 0
Call: INSERT INTO pretoria.joueurs (ID, BLOQUE, cle_validation, creation, EMAIL, LANGAGE, maj_temperament, NEWSLETTER, PASSWORD, POUSSIERE, SEL, TEMPERAMENT, VACANCES, VERSION, alliance_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    bind => [15 parameters bound]
Query: InsertObjectQuery(com.sim.entities.Joueur@1a21ad9)
    at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:333)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.processExceptionForCommError(DatabaseAccessor.java:1494)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:838)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:906)
    ................
Caused by: org.postgresql.util.PSQLException: ERREUR: la transaction est annulée, les commandes sont ignorées jusqu'à la fin du bloc
de la transaction
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2102)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1835)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:500)
    ................
|#]

[#|2013-01-10T15:03:28.234+0100|WARNING|glassfish3.1.2|javax.enterprise.system.core.transaction.com.sun.jts.jta|_ThreadID=72;_ThreadName=Thread-2;|JTS5054: Unexpected error occurred in after completion
Local Exception Stack: 
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERREUR: la transaction est annulée, les commandes sont ignorées jusqu'à la fin du bloc
de la transaction
Error Code: 0
Call: INSERT INTO pretoria.joueurs (ID, BLOQUE, cle_validation, creation, EMAIL, LANGAGE, maj_temperament, NEWSLETTER, PASSWORD, POUSSIERE, SEL, TEMPERAMENT, VACANCES, VERSION, alliance_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    bind => [15 parameters bound]
Query: InsertObjectQuery(com.sim.entities.Joueur@1a21ad9)
    at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:333)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.processExceptionForCommError(DatabaseAccessor.java:1494)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:838)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:906)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:592)
    ................
Caused by: org.postgresql.util.PSQLException: ERREUR: la transaction est annulée, les commandes sont ignorées jusqu'à la fin du bloc
de la transaction
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2102)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1835)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:500)
    ................
|#]

[#|2013-01-10T15:03:28.234+0100|WARNING|glassfish3.1.2|javax.enterprise.system.container.ejb.com.sun.ejb.containers|_ThreadID=72;_ThreadName=Thread-2;|EJB5184:A system exception occurred during an invocation on EJB AccountBean, method: public void com.sim.ejbs.stateless.AccountBean.createAccount(java.lang.String,char[],java.lang.String,com.sim.basics.enums.TemperamentEnum,com.sim.dtos.xml.universes.Universe,int,int,int,java.lang.String,java.lang.String) throws com.sim.basics.exceptions.SimRuntimeException|#]

[#|2013-01-10T15:03:28.234+0100|WARNING|glassfish3.1.2|javax.enterprise.system.container.ejb.com.sun.ejb.containers|_ThreadID=72;_ThreadName=Thread-2;|javax.ejb.EJBException: Transaction aborted
    at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:5142)
    at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4901)
    at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2045)
    at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1994)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:222)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:89)
    ................
Caused by: javax.transaction.RollbackException
    at com.sun.jts.jta.TransactionManagerImpl.commit(TransactionManagerImpl.java:334)
    at com.sun.enterprise.transaction.jts.JavaEETransactionManagerJTSDelegate.commitDistributedTransaction(JavaEETransactionManagerJTSDelegate.java:185)
    at com.sun.enterprise.transaction.JavaEETransactionManagerSimplified.commit(JavaEETransactionManagerSimplified.java:861)
    at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:5136)
    ... 53 more
|#]

Log4j日志:

2013-01-10 15:03:28,218 FATAL   [com.sim.ejbs.stateless.AccountBean] 

javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERREUR: le pseudo est déjà pris (player_name)=(hghghghggg)
Error Code: 0
Call: INSERT INTO pretoria.pseudos (ID, CHANGEMENT, PSEUDO, VERSION, joueur_id) VALUES (?, ?, ?, ?, ?)
    bind => [5 parameters bound]
Query: InsertObjectQuery(com.sim.entities.Pseudo@190c460)
2013-01-10 15:03:28,234 FATAL   [com.sim.web.beans.LoginBean] 123

2 个答案:

答案 0 :(得分:1)

IIRC一些数据库实际上可能会在事务提交时执行语句,因此请尝试调用commit(而不是flush(),仅用于测试)并查看是否也发生了。

编辑:另一方面,JPA需要在完成之后立即获取持久化实体的ID(如果生成策略是IDENTITY或SEQUENCE),那么可能是我上面所说的不正确...

答案 1 :(得分:0)

是的,冲洗总是冲洗。您可能没有执行您认为自己的代码,也可能没有获得您期望的异常。启用最好的登录,然后尝试调试。