Donatas Veikutis
Donatas Veikutis

Reputation: 1004

JPA multithreading org.eclipse.persistence.exceptions.ConcurrencyException

Hi I try to do multithreading with JSOUP and JPA to parse some pages and put the information in database, but I sometimes get this exception:

Exception in thread "Thread-7" Local Exception Stack: 
Exception [EclipseLink-2004] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.ConcurrencyException
Exception Description: A signal was attempted before wait() on ConcurrencyManager. This normally means that an attempt was made to 
commit or rollback a transaction before it was started, or to rollback a transaction twice.
    at org.eclipse.persistence.exceptions.ConcurrencyException.signalAttemptedBeforeWait(ConcurrencyException.java:84)
    at org.eclipse.persistence.internal.helper.ConcurrencyManager.releaseReadLock(ConcurrencyManager.java:489)
    at org.eclipse.persistence.internal.identitymaps.CacheKey.releaseReadLock(CacheKey.java:386)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.cloneAndRegisterObject(UnitOfWorkImpl.java:1015)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildWorkingCopyCloneNormally(ObjectBuilder.java:731)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObjectInUnitOfWork(ObjectBuilder.java:668)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:601)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:560)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.buildObject(ObjectLevelReadQuery.java:717)
    at org.eclipse.persistence.queries.ReadAllQuery.registerResultInUnitOfWork(ReadAllQuery.java:769)
    at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:433)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1081)
    at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:844)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1040)
    at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:392)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1128)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2871)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1516)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1498)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1463)
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.executeReadQuery(EJBQueryImpl.java:485)
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.getSingleResult(EJBQueryImpl.java:773)
    at database.dao.LinkDAO.getLinkByLink(LinkDAO.java:23)
    at celsis.CelsisGijos.parsePreke(CelsisGijos.java:160)
    at celsis.CelsisGijos.runThruePrekes(CelsisGijos.java:139)
    at celsis.CelsisGijos.runThrueGrupes(CelsisGijos.java:67)
    at celsis.CelsisGijos.run(CelsisGijos.java:314)

It appears in this method in Line 3:

1    public static synchronized XParserLinks getLinkByLink(String link) {
2        try {
3            XParserLinks obj = TarpineManager.getInstance().createNamedQuery("XParserLinks.findByLink", XParserLinks.class).setParameter("link", link).getSingleResult();
4            return obj;
5        } catch (NoResultException e) {
6            return null;
7        }
8        
9    }

Upvotes: 3

Views: 3790

Answers (1)

Hasan Ceylan
Hasan Ceylan

Reputation: 591

JPA and EntityManager is not thread-safe.

You need to create an entity manager for each of the worker threads in your application.

See section 7.2 in JPA Spec:

7.2 Obtaining an EntityManager

An entity manager must not be shared among multiple concurrently executing threads, as the entity manager and persistence context are not required to be threadsafe. Entity managers must only be accessed in a single-threaded manner.

Upvotes: 8

Related Questions