Olivier J.
Olivier J.

Reputation: 3175

EntityManager.flush() not flushing immediately?

I have this code in 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);             
}

This code must throw Exception because I have made trigger (via PostGreQSL) to check some constraint and I use test values to launch my trigger.

I have a weird result because my logs display test so I enter the catch block but my code does not catch "all" or the "complete" Exception because my server log displays all Exception stack and I don't know why...It's look like this code throws Exception after...

I know that I have to call flush() method to immediately store entities into my database but it's look like it doesn't work here and an Exception is still propagated into my code.

Few weeks ago this code worked but I have worked on another project facet and now it seems that I have some kind of regression and I don't know why...

So my question is this one : does EntityManager.flush() always perform persist action immediately?

EDIT : here are my logs (a little epurated) (first->GF log, second->Log4j personnal log) : Sorry it's French version, but Exception name remain the same ;)

[#|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 log :

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

Upvotes: 1

Views: 3710

Answers (2)

Adam Dyga
Adam Dyga

Reputation: 8926

IIRC some databases may actually execute the statements on transaction commit, so please try to invoke commit (instead of flush(), just for testing) and see if it happens too.

EDIT: On the other hand JPA needs to get ID of persisted entity right after it's done (if the generation strategy is IDENTITY or SEQUENCE), so probably it's not right what I said above...

Upvotes: 1

James
James

Reputation: 18389

Yes, flush will always flush. You may not be executing the code you think you are, or may not be getting the exception you expect. Enable logging on finest, and try debugging.

Upvotes: 0

Related Questions