openjpa-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Craig L Russell <Craig.Russ...@Sun.COM>
Subject Re: why not an EntityExistsException was thrown?
Date Wed, 04 Apr 2007 15:21:07 GMT
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:wanyna@hotmail.com]
>>> 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: generate.Bsc@5d391d
>>> 	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:wanyna@hotmail.com]
>>>>> 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: generate.Bsc@5d391d
>>>>> 	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: generate.Bsc@14b6bed
>>>>> 	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:generate.Bsc@14b6bed
>>>>>
>>>>> 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
clr@apache.org http://db.apache.org/jdo



Mime
View raw message