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*

Reply via email to