Surely you are right. The object to persist is just in the result of query. I'v made a mistake in my test case 2, I did not notice some relations. Thanks.
Craig L Russell wrote: > > Hi Wanyna, > > Whenever you query for entities, the result entities are put into > your persistence context. So when you then try to persist another > entity with the same identity the provider finds the query result in > the persistence context and throws EntityExistsException. > > Craig > > On Apr 4, 2007, at 9:47 PM, wanyna wrote: > >> >> Your explaination is clearly if I only show my test case 1. >> My test case 2, add a query before persist, then get >> EntityExistsException. >> The result of query hold some object no association with the >> object to >> persist. >> Why this time the object exists in persistence context? >> >> >> >> Craig L Russell wrote: >>> >>> If you look at the exception that is thrown from the database, it's a >>> pretty general exception. >>> >>> "The statement was aborted because it would have caused a duplicate >>> key value in a unique or primary key constraint or unique index >>> identified by 'SQL070403054930170' defined on 'BSC'." >>> >>> This might have been caused by a unique constraint, which would not >>> be properly reported as EntityExistsException. >>> >>> Sadly, there is no standard SQL exception that specifically tells the >>> provider (OpenJPA) that there was a primary key constraint violation. >>> And you might also note that every database has its own way to report >>> exceptions like this. >>> >>> What the EntityExistsException does is to report that there is >>> already an entity with the same primary key in the persistence >>> context. It doesn't report that there was a problem writing the >>> entity to the database. >>> >>> If you're looking for better error reporting you can flush as part of >>> the application-level persist operation. That way your application >>> can catch a persistence exception that is caused either by persist or >>> flush and report it as a "problem persisting entity" to your caller. >>> >>> But there is a down side to this. If you flush immediately after >>> persist, the provider cannot optimize for performance. So it's a >>> tradeoff that you need to make in your application. >>> >>> If you're keen on "fixing" this situation, I'd encourage you to >>> volunteer to look at the databases and how they report unique and >>> primary key constraint violations and see if it's possible to parse >>> the sql code and report string to positively identify a primary key >>> constraint violation. >>> >>> Craig >>> >>> On Apr 3, 2007, at 9:42 PM, wanyna wrote: >>> >>>> >>>> I can't find EntityExistsException nested in RollbackExceptions. >>>> http://www.nabble.com/file/7646/exception.jpg >>>> >>>> Will exception mechanism be planned to improve? >>>> I think it's very important. >>>> >>>> >>>> Patrick Linskey wrote: >>>>> >>>>> Cool -- that explains it then. >>>>> >>>>> EM.commit() must throw RollbackExceptions (and >>>>> org.apache.openjpa.persistence.RollbackException extends >>>>> javax.persistence.RollbackException) when the transaction is >>>>> rolled back >>>>> during the course of the commit. >>>>> >>>>> If you get the nested exception from the RollbackException, I bet >>>>> that >>>>> it's instanceof EntityExistsException. >>>>> >>>>> Clearly, however, something is wonky with our exception printing >>>>> algorithm. >>>>> >>>>> -Patrick >>>>> >>>>> -- >>>>> Patrick Linskey >>>>> BEA Systems, Inc. >>>>> >>>>> ___________________________________________________________________ >>>>> __ >>>>> __ >>>>> Notice: This email message, together with any attachments, may >>>>> contain >>>>> information of BEA Systems, Inc., its subsidiaries and >>>>> affiliated >>>>> entities, that may be confidential, proprietary, copyrighted >>>>> and/or >>>>> legally privileged, and is intended solely for the use of the >>>>> individual >>>>> or entity named in this message. If you are not the intended >>>>> recipient, >>>>> and have received this message in error, please immediately return >>>>> this >>>>> by email and then delete it. >>>>> >>>>>> -----Original Message----- >>>>>> From: wanyna [mailto:[EMAIL PROTECTED] >>>>>> Sent: Tuesday, April 03, 2007 8:49 PM >>>>>> To: open-jpa-dev@incubator.apache.org >>>>>> Subject: RE: why not an EntityExistsException was thrown? >>>>>> >>>>>> >>>>>> actual class of the exception: >>>>>> class org.apache.openjpa.persistence.RollbackException >>>>>> <2|true|0.9.7-incubating-SNAPSHOT> >>>>>> org.apache.openjpa.persistence.RollbackException: The >>>>>> transaction has been >>>>>> rolled back. See the nested exceptions for details on the errors >>>>>> that >>>>>> occurred. >>>>>> at >>>>>> org.apache.openjpa.persistence.EntityManagerImpl.commit(Entity >>>>>> ManagerImpl.java:417) >>>>>> at test.Main.main(Main.java:82) >>>>>> Caused by: <0|true|0.9.7-incubating-SNAPSHOT> >>>>>> org.apache.openjpa.persistence.PersistenceException: The >>>>>> transaction has >>>>>> been rolled back. See the nested exceptions for details on >>>>>> the errors that >>>>>> occurred. >>>>>> at >>>>>> org.apache.openjpa.kernel.BrokerImpl.newFlushException(BrokerI >>>>>> mpl.java:2091) >>>>>> at >>>>>> org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:1938) >>>>>> at >>>>>> org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java: >>>>>> 1836) >>>>>> at >>>>>> org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerIm >>>>>> pl.java:1754) >>>>>> at >>>>>> org.apache.openjpa.kernel.LocalManagedRuntime.commit(LocalMana >>>>>> gedRuntime.java:76) >>>>>> at >>>>>> org.apache.openjpa.kernel.BrokerImpl.commit(BrokerImpl.java:1311) >>>>>> at >>>>>> org.apache.openjpa.kernel.DelegatingBroker.commit(DelegatingBr >>>>>> oker.java:863) >>>>>> at >>>>>> org.apache.openjpa.persistence.EntityManagerImpl.commit(Entity >>>>>> ManagerImpl.java:406) >>>>>> ... 1 more >>>>>> Caused by: <0|false|0.9.7-incubating-SNAPSHOT> >>>>>> org.apache.openjpa.persistence.PersistenceException: The >>>>>> statement was >>>>>> aborted because it would have caused a duplicate key value in >>>>>> a unique or >>>>>> primary key constraint or unique index identified by >>>>>> 'SQL070403054930170' >>>>>> defined on 'BSC'. {prepstmnt 15774883 INSERT INTO BSC (objid, >>>>>> objname, >>>>>> created, msc_name, objclass) VALUES (?, ?, ?, ?, ?) [params= >>>>>> (long) 1, >>>>>> (String) objname1, (Timestamp) 2006-05-04 18:13:51.0, >>>>>> (String) objname0, >>>>>> (String) bsc]} [code=-1, state=23505] >>>>>> FailedObject: [EMAIL PROTECTED] >>>>>> at >>>>>> org.apache.openjpa.jdbc.sql.DBDictionary.newStoreException(DBD >>>>>> ictionary.java:3764) >>>>>> at >>>>>> org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptio >>>>>> ns.java:94) >>>>>> at >>>>>> org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptio >>>>>> ns.java:64) >>>>>> at >>>>>> org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.fl >>>>>> ushInternal(PreparedStatementManagerImpl.java:103) >>>>>> at >>>>>> org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.fl >>>>>> ush(PreparedStatementManagerImpl.java:68) >>>>>> at >>>>>> org.apache.openjpa.jdbc.kernel.OperationOrderUpdateManager.flu >>>>>> shPrimaryRow(OperationOrderUpdateManager.java:200) >>>>>> at >>>>>> org.apache.openjpa.jdbc.kernel.OperationOrderUpdateManager.flu >>>>>> sh(OperationOrderUpdateManager.java:86) >>>>>> at >>>>>> org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(Abs >>>>>> tractUpdateManager.java:86) >>>>>> at >>>>>> org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(Abs >>>>>> tractUpdateManager.java:69) >>>>>> at >>>>>> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.flush(JDBCStor >>>>>> eManager.java:511) >>>>>> at >>>>>> org.apache.openjpa.kernel.DelegatingStoreManager.flush(Delegat >>>>>> ingStoreManager.java:127) >>>>>> ... 8 more >>>>>> Caused by: org.apache.openjpa.lib.jdbc.ReportingSQLException: >>>>>> The statement >>>>>> was aborted because it would have caused a duplicate key >>>>>> value in a unique >>>>>> or primary key constraint or unique index identified by >>>>>> 'SQL070403054930170' >>>>>> defined on 'BSC'. {prepstmnt 15774883 INSERT INTO BSC (objid, >>>>>> objname, >>>>>> created, msc_name, objclass) VALUES (?, ?, ?, ?, ?) [params= >>>>>> (long) 1, >>>>>> (String) objname1, (Timestamp) 2006-05-04 18:13:51.0, >>>>>> (String) objname0, >>>>>> (String) bsc]} [code=-1, state=23505] >>>>>> at >>>>>> org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.wrap(Lo >>>>>> ggingConnectionDecorator.java:188) >>>>>> at >>>>>> org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.access$ >>>>> 800(LoggingConnectionDecorator.java:53) >>>>>> at >>>>>> org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator$Logging >>>>>> Connection$LoggingPreparedStatement.executeUpdate(LoggingConne >>>>>> ctionDecorator.java:854) >>>>>> at >>>>>> org.apache.openjpa.lib.jdbc.DelegatingPreparedStatement.execut >>>>>> eUpdate(DelegatingPreparedStatement.java:266) >>>>>> at >>>>>> org.apache.openjpa.jdbc.kernel.JDBCStoreManager$CancelPrepared >>>>> Statement.executeUpdate(JDBCStoreManager.java:1360) >>>>>> at >>>>>> org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.fl >>>>>> ushInternal(PreparedStatementManagerImpl.java:92) >>>>>> ... 15 more >>>>>> FailedObject:null >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> Patrick Linskey wrote: >>>>>>> >>>>>>>> <2|true|0.9.7-incubating-SNAPSHOT> >>>>>>> org.apache.openjpa.util.StoreException: >>>>>>> >>>>>>> You definitely should not be getting that exception -- >>>>>> OpenJPA should >>>>>>> only be throwing exception types that are in the >>>>>>> org.apache.openjpa.persistence package and sub-packages. >>>>>>> >>>>>>> Can you print out the actual class of the exception that is >>>>>>> thrown >>>>>>> (i.e., System.err.println(e.getClass()) just in case the >>>>>> exception is >>>>>>> just doing a bad job of printing itself out? >>>>>>> >>>>>>> Thanks, >>>>>>> >>>>>>> -Patrick >>>>>>> >>>>>>> -- >>>>>>> Patrick Linskey >>>>>>> BEA Systems, Inc. >>>>>>> >>>>>>> >>>>>> ______________________________________________________________ >>>>>> _________ >>>>>>> Notice: This email message, together with any attachments, >>>>>> may contain >>>>>>> information of BEA Systems, Inc., its subsidiaries and >>>>>> affiliated >>>>>>> entities, that may be confidential, proprietary, >>>>>> copyrighted and/or >>>>>>> legally privileged, and is intended solely for the use of >>>>>> the individual >>>>>>> or entity named in this message. If you are not the >>>>>> intended recipient, >>>>>>> and have received this message in error, please immediately >>>>>> return this >>>>>>> by email and then delete it. >>>>>>> >>>>>>>> -----Original Message----- >>>>>>>> From: wanyna [mailto:[EMAIL PROTECTED] >>>>>>>> Sent: Tuesday, April 03, 2007 8:26 PM >>>>>>>> To: open-jpa-dev@incubator.apache.org >>>>>>>> Subject: why not an EntityExistsException was thrown? >>>>>>>> >>>>>>>> >>>>>>>> I was confused in result of my test cases. >>>>>>>> My test is about JPA exceptions. I use derby in my tests. >>>>>>>> The first case is simply persist an object, the PK of the >>>>>>>> object has existed >>>>>>>> in database, >>>>>>>> so exception arose. >>>>>>>> entityManager = factory.createEntityManager(); >>>>>>>> entityManager.getTransaction().begin(); >>>>>>>> ... >>>>>>>> entityManager.persist(anObject); >>>>>>>> entityManager.getTransaction().commit(); >>>>>>>> exception is: >>>>>>>> <2|true|0.9.7-incubating-SNAPSHOT> >>>>>>>> org.apache.openjpa.util.StoreException: >>>>>>>> The transaction has been rolled back. See the nested >>>>>>>> exceptions for details >>>>>>>> on the errors that occurred. >>>>>>>> at >>>>>>>> org.apache.openjpa.kernel.BrokerImpl.newFlushException(BrokerI >>>>>>>> mpl.java:2091) >>>>>>>> at >>>>>>>> org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:1938) >>>>>>>> at >>>>>>>> >>>>>> org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java: >>>>>> 1836) >>>>>>>> at >>>>>>>> org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerIm >>>>>>>> pl.java:1754) >>>>>>>> at >>>>>>>> org.apache.openjpa.kernel.LocalManagedRuntime.commit(LocalMana >>>>>>>> gedRuntime.java:76) >>>>>>>> at >>>>>>>> org.apache.openjpa.kernel.BrokerImpl.commit(BrokerImpl.java: >>>>>>>> 1311) >>>>>>>> at >>>>>>>> org.apache.openjpa.kernel.DelegatingBroker.commit(DelegatingBr >>>>>>>> oker.java:863) >>>>>>>> at >>>>>>>> org.apache.openjpa.persistence.EntityManagerImpl.commit(Entity >>>>>>>> ManagerImpl.java:406) >>>>>>>> at test.Main.main(Main.java:82) >>>>>>>> Caused by: <2|false|0.9.7-incubating-SNAPSHOT> >>>>>>>> org.apache.openjpa.util.StoreException: The statement was >>>>>>>> aborted because it >>>>>>>> would have caused a duplicate key value in a unique or >>>>>>>> primary key >>>>>>>> constraint or unique index identified by 'SQL070403054930170' >>>>>>>> defined on >>>>>>>> 'BSC'. {prepstmnt 15774883 INSERT INTO BSC (objid, >>>>>> objname, created, >>>>>>>> msc_name, objclass) VALUES (?, ?, ?, ?, ?) [params=(long) >>>>>> 1, (String) >>>>>>>> objname1, (Timestamp) 2006-05-04 18:13:51.0, (String) >>>>>>>> objname0, (String) >>>>>>>> bsc]} [code=-1, state=23505] >>>>>>>> FailedObject: [EMAIL PROTECTED] >>>>>>>> at >>>>>>>> org.apache.openjpa.jdbc.sql.DBDictionary.newStoreException(DBD >>>>>>>> ictionary.java:3764) >>>>>>>> at >>>>>>>> org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptio >>>>>>>> ns.java:94) >>>>>>>> at >>>>>>>> org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptio >>>>>>>> ns.java:64) >>>>>>>> at >>>>>>>> org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.fl >>>>>>>> ushInternal(PreparedStatementManagerImpl.java:103) >>>>>>>> at >>>>>>>> org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.fl >>>>>>>> ush(PreparedStatementManagerImpl.java:68) >>>>>>>> at >>>>>>>> org.apache.openjpa.jdbc.kernel.OperationOrderUpdateManager.flu >>>>>>>> shPrimaryRow(OperationOrderUpdateManager.java:200) >>>>>>>> at >>>>>>>> org.apache.openjpa.jdbc.kernel.OperationOrderUpdateManager.flu >>>>>>>> sh(OperationOrderUpdateManager.java:86) >>>>>>>> at >>>>>>>> org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(Abs >>>>>>>> tractUpdateManager.java:86) >>>>>>>> at >>>>>>>> org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(Abs >>>>>>>> tractUpdateManager.java:69) >>>>>>>> at >>>>>>>> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.flush(JDBCStor >>>>>>>> eManager.java:511) >>>>>>>> at >>>>>>>> org.apache.openjpa.kernel.DelegatingStoreManager.flush(Delegat >>>>>>>> ingStoreManager.java:127) >>>>>>>> ... 8 more >>>>>>>> Caused by: org.apache.openjpa.lib.jdbc.ReportingSQLException: >>>>>>>> The statement >>>>>>>> was aborted because it would have caused a duplicate key >>>>>>>> value in a unique >>>>>>>> or primary key constraint or unique index identified by >>>>>>>> 'SQL070403054930170' >>>>>>>> defined on 'BSC'. {prepstmnt 15774883 INSERT INTO BSC >>>>>> (objid, objname, >>>>>>>> created, msc_name, objclass) VALUES (?, ?, ?, ?, ?) >>>>>> [params=(long) 1, >>>>>>>> (String) objname1, (Timestamp) 2006-05-04 18:13:51.0, >>>>>>>> (String) objname0, >>>>>>>> (String) bsc]} [code=-1, state=23505] >>>>>>>> at >>>>>>>> org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.wrap(Lo >>>>>>>> ggingConnectionDecorator.java:188) >>>>>>>> at >>>>>>>> org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.access$ >>>>>>> 800(LoggingConnectionDecorator.java:53) >>>>>>>> at >>>>>>>> org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator$Logging >>>>>>> Connection> >>>>>>> $LoggingPreparedStatement.executeUpdate(LoggingConnectionDecor >>>>>>>> ator.java:854) >>>>>>>> at >>>>>>>> org.apache.openjpa.lib.jdbc.DelegatingPreparedStatement.execut >>>>>>>> eUpdate(DelegatingPreparedStatement.java:266) >>>>>>>> at >>>>>>>> org.apache.openjpa.jdbc.kernel.JDBCStoreManager$CancelPrepared >>>>>>> Statement.executeUpdate(JDBCStoreManager.java:1360) >>>>>>>> at >>>>>>>> org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.fl >>>>>>>> ushInternal(PreparedStatementManagerImpl.java:92) >>>>>>>> ... 15 more >>>>>>>> >>>>>>>> I wonder why not an EntityExistsException was thrown? >>>>>>>> >>>>>>>> In the second case, I add a query before persist, >>>>>>>> entityManager = factory.createEntityManager(); >>>>>>>> /* >>>>>>>> * query before persist, even bofore >>>>>>>> transaction effects samely. >>>>>>>> * this query makes exception thrown in >>>>>>>> persist section difference. >>>>>>>> * it seems that query what entity is >>>>>>>> not important, >>>>>>>> * but must get result and result must >>>>>>>> has some record. >>>>>>>> */ >>>>>>>> entityManager.createQuery(jpql).getResultList(); >>>>>>>> >>>>>>>> entityManager.getTransaction().begin(); >>>>>>>> ... >>>>>>>> entityManager.persist(anObject); >>>>>>>> entityManager.getTransaction().commit(); >>>>>>>> exception: >>>>>>>> <2|false|0.9.7-incubating-SNAPSHOT> >>>>>>>> org.apache.openjpa.persistence.EntityExistsException: An >>>>>>>> object of type >>>>>>>> "generate.Bsc" with oid "generate.Bsc-1:objname1" already >>>>>>>> exists in this >>>>>>>> context; another cannot be persisted. >>>>>>>> FailedObject: [EMAIL PROTECTED] >>>>>>>> at >>>>>>>> org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java: >>>>>>>> 2370) >>>>>>>> at >>>>>>>> org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java: >>>>>>>> 2206) >>>>>>>> at >>>>>>>> org.apache.openjpa.kernel.DelegatingBroker.persist(DelegatingB >>>>>>>> roker.java:991) >>>>>>>> at >>>>>>>> org.apache.openjpa.persistence.EntityManagerImpl.persist(Entit >>>>>>>> yManagerImpl.java:526) >>>>>>>> at test.Main.main(Main.java:72) >>>>>>>> FailedObject:[EMAIL PROTECTED] >>>>>>>> >>>>>>>> An EntityExistsException was thrown this time, why? >>>>>>>> >>>>>>>> Exception is different, and when exception was thrown is also >>>>>>>> different. >>>>>>>> first case exception was caught at commit, >>>>>>>> second case, exception was caught at persist, why? >>>>>>>> >>>>>>>> -- >>>>>>>> View this message in context: >>>>>>>> http://www.nabble.com/why-not-an-EntityExistsException-was-thr >>>>>>> own--tf3523673.html#a9830350 >>>>>>>> Sent from the open-jpa-dev mailing list archive at Nabble.com. >>>>>>>> >>>>>>>> >>>>>>> >>>>>>> Notice: This email message, together with any attachments, >>>>>> may contain >>>>>>> information of BEA Systems, Inc., its subsidiaries and >>>>>> affiliated >>>>>>> entities, that may be confidential, proprietary, >>>>>> copyrighted and/or >>>>>>> legally privileged, and is intended solely for the use of >>>>>> the individual >>>>>>> or entity named in this message. If you are not the >>>>>> intended recipient, >>>>>>> and have received this message in error, please immediately >>>>>> return this by >>>>>>> email and then delete it. >>>>>>> >>>>>>> >>>>>> >>>>>> -- >>>>>> View this message in context: >>>>>> http://www.nabble.com/why-not-an-EntityExistsException-was-thr >>>>>> own--tf3523673.html#a9830521 >>>>>> Sent from the open-jpa-dev mailing list archive at Nabble.com. >>>>>> >>>>>> >>>>> >>>>> Notice: This email message, together with any attachments, may >>>>> contain >>>>> information of BEA Systems, Inc., its subsidiaries and >>>>> affiliated >>>>> entities, that may be confidential, proprietary, copyrighted >>>>> and/or >>>>> legally privileged, and is intended solely for the use of the >>>>> individual >>>>> or entity named in this message. If you are not the intended >>>>> recipient, >>>>> and have received this message in error, please immediately return >>>>> this by >>>>> email and then delete it. >>>>> >>>>> >>>> >>>> -- >>>> View this message in context: http://www.nabble.com/why-not-an- >>>> EntityExistsException-was-thrown--tf3523673.html#a9830907 >>>> Sent from the open-jpa-dev mailing list archive at Nabble.com. >>>> >>> >>> Craig Russell >>> DB PMC, OpenJPA PPMC >>> [EMAIL PROTECTED] http://db.apache.org/jdo >>> >>> >>> >>> >>> >> >> -- >> View this message in context: http://www.nabble.com/why-not-an- >> EntityExistsException-was-thrown--tf3523673.html#a9850020 >> Sent from the open-jpa-dev mailing list archive at Nabble.com. >> > > Craig Russell > Architect, Sun Java Enterprise System http://java.sun.com/products/jdo > 408 276-5638 mailto:[EMAIL PROTECTED] > P.S. A good JDO? O, Gasp! > > > > -- View this message in context: http://www.nabble.com/why-not-an-EntityExistsException-was-thrown--tf3523673.html#a9866906 Sent from the open-jpa-dev mailing list archive at Nabble.com.