> 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*

Reply via email to