Is this your scenario? T1: Find id=1, returns null T2: Find id=1, returns null
T1: merge(id=1) T2: merge(id=1) T1: tran commit T2: tran commit, EntityExistsException If so, it sounds like you need to add some exception handling? On Tue, Jul 10, 2012 at 11:04 AM, Daniel Persson <mailto.wo...@gmail.com>wrote: > Correct but I'm merging entities. And if the find returns null I'll create > an new entity. > On Jul 10, 2012 5:11 PM, "Rick Curtis" <curti...@gmail.com> wrote: > > > > I have a problem with one of our entities that we write in a callable > > thread that could be called multiple times simultaneously. > > If I'm reading this correctly, you're trying to persist an Entity with > the > > same ID multiple times simultaneously? If that is the case, this > exception > > is expected. > > > > On Tue, Jul 10, 2012 at 10:00 AM, Daniel Persson <mailto.wo...@gmail.com > > >wrote: > > > > > Hi OpenJPA users. > > > > > > I have a problem with one of our entities that we write in a callable > > > thread that could be called multiple times simultaneously. > > > > > > We have an ThreadPoolExecutor that runs multiple versions of an object > > > implements Callable. > > > In some of these objects an entity is fetched and merged. > > > > > > We seperate each thread using ThreadLocal so each thread has there own > > > entityManager and it uses it during the thread execution. > > > private static transient ThreadLocal<Hashtable<String, EntityManager>> > > > entityManagers = new ThreadLocal<Hashtable<String, EntityManager>>(); > > > > > > No entities is sent between threads. > > > > > > The error we get frequently: > > > > > > Caused by: <openjpa-2.2.1-SNAPSHOT-r422266:1352927M fatal store error> > > > org.apache.openjpa.persistence.EntityExistsException: Duplicate entry > > > '472307' for key 1 {prepstmnt 37611 INSERT INTO table(col1, col2, > > > col3, col4) VALUES (?, ?, ?, ?)} [code=1062, state=23000] > > > FailedObject: path.to.table@3725f1 > > > at > > > org.apache.openjpa.jdbc.sql.DBDictionary.narrow(DBDictionary.java:4926) > > > at > > > > > > org.apache.openjpa.jdbc.sql.DBDictionary.newStoreException(DBDictionary.java:4901) > > > at > > > > > > org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:136) > > > at > > > > org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:78) > > > at > > > > > > org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flushAndUpdate(PreparedStatementManagerImpl.java:143) > > > at > > > > > > org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flushInternal(PreparedStatementManagerImpl.java:99) > > > at > > > > > > org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flush(PreparedStatementManagerImpl.java:87) > > > at > > > > > > org.apache.openjpa.jdbc.kernel.OperationOrderUpdateManager.flushPrimaryRow(OperationOrderUpdateManager.java:203) > > > at > > > > > > org.apache.openjpa.jdbc.kernel.OperationOrderUpdateManager.flush(OperationOrderUpdateManager.java:89) > > > at > > > > > > org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:105) > > > at > > > > > > org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:78) > > > at > > > > > > org.apache.openjpa.jdbc.kernel.JDBCStoreManager.flush(JDBCStoreManager.java:738) > > > at > > > > > > org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:131) > > > at > > > > > > org.apache.openjpa.datacache.DataCacheStoreManager.flush(DataCacheStoreManager.java:661) > > > at > > > > > > org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:131) > > > ... 19 more > > > Caused by: org.apache.openjpa.lib.jdbc.ReportingSQLException: > > > Duplicate entry '472307' for key 1 {prepstmnt 37611 INSERT INTO > > > table(col1, col2, col3, col4) VALUES (?, ?, ?, ?)} [code=1062, > > > state=23000] > > > at > > > > > > org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.wrap(LoggingConnectionDecorator.java:219) > > > at > > > > > > org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.wrap(LoggingConnectionDecorator.java:195) > > > at > > > > > > org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.access$1000(LoggingConnectionDecorator.java:59) > > > at > > > > > > org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator$LoggingConnection$LoggingPreparedStatement.executeUpdate(LoggingConnectionDecorator.java:1134) > > > at > > > > > > org.apache.openjpa.lib.jdbc.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:272) > > > at > > > > > > org.apache.openjpa.jdbc.kernel.JDBCStoreManager$CancelPreparedStatement.executeUpdate(JDBCStoreManager.java:1768) > > > at > > > > > > org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.executeUpdate(PreparedStatementManagerImpl.java:267) > > > at > > > > > > org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flushAndUpdate(PreparedStatementManagerImpl.java:118) > > > ... 29 more > > > > > > Our persistance configuration using an non-jta-data-source and tomcat > > > datasource pooling. > > > > > > <property name="openjpa.ConnectionDriverName" > > > value="com.mysql.jdbc.Driver" /> > > > <property name="openjpa.ConnectionProperties" > > > value="autoReconnect=false,connectTimeout=5,socketTimeout=5" /> > > > <property name="openjpa.jdbc.DBDictionary" > > > value="mysql(SupportsSubselect=true,UseClobs=true)"/> > > > <property name="openjpa.jdbc.UpdateManager" value="operation-order"/> > > > <property name="openjpa.DataCache" value="true(CacheSize=1000, > > > SoftReferenceSize=0, EnableStatistics=true)"/> > > > <property name="openjpa.QueryCache" value="true(CacheSize=200, > > > SoftReferenceSize=0, EvictPolicy='timestamp')"/> > > > <property name="openjpa.Log" value="File=/tmp/openjpa.log, > > > DefaultLevel=WARN, Runtime=WARN, Tool=WARN, SQL=WARN"/> > > > <property name="openjpa.DetachState" > > > value="fetch-groups(DetachedStateField=true)"/> > > > <property name="openjpa.FetchBatchSize" value="0"/> > > > <property name="openjpa.InverseManager" value="true"/> > > > > > > Any suggestions how to proceed? > > > My guess is that one thread writes an entity before the another thread > > > and the EntityManager entity state isn't updated before the next > > > merge. > > > > > > Best regards > > > > > > Daniel > > > > > > > > > > > -- > > *Rick Curtis* > > > -- *Rick Curtis*