简体   繁体   中英

Eclipselink throwing ConcurrentModificationException

I'm having problems with some ConcurrentModificationException in a code of an application:

   Caused by: Exception [EclipseLink-2004] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): 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:392)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.cloneAndRegisterObject(UnitOfWorkImpl.java:1022)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.cloneAndRegisterObject(UnitOfWorkImpl.java:933)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkIdentityMapAccessor.getAndCloneCacheKeyFromParent(UnitOfWorkIdentityMapAccessor.java:197)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkIdentityMapAccessor.getFromIdentityMap(UnitOfWorkIdentityMapAccessor.java:125)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerExistingObject(UnitOfWorkImpl.java:3920)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerExistingObject(UnitOfWorkImpl.java:3874)
        at org.eclipse.persistence.mappings.ObjectReferenceMapping.buildUnitofWorkCloneForPartObject(ObjectReferenceMapping.java:109)
        at org.eclipse.persistence.mappings.ObjectReferenceMapping.buildCloneForPartObject(ObjectReferenceMapping.java:71)
        at org.eclipse.persistence.internal.indirection.UnitOfWorkQueryValueHolder.buildCloneFor(UnitOfWorkQueryValueHolder.java:56)
        at org.eclipse.persistence.internal.indirection.UnitOfWorkValueHolder.instantiateImpl(UnitOfWorkValueHolder.java:161)
        at org.eclipse.persistence.internal.indirection.UnitOfWorkValueHolder.instantiate(UnitOfWorkValueHolder.java:222)
        at org.eclipse.persistence.internal.indirection.DatabaseValueHolder.getValue(DatabaseValueHolder.java:88)

Analising the code, I've found the class responsible for provide the EntityManager:

import javax.ejb.Stateful;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import weblogic.javaee.CallByReference;

@Stateful (name = "DAOFactoryRemoteBean", mappedName = "DAOFactoryRemoteBean")
@CallByReference
public class DAOFactoryRemoteImplBean implements DAOFactoryRemoteBean {

    @PersistenceContext(unitName = "server_unit")
    private EntityManager em;

    private static String getDAOName(Class<?> classeEntidade) {
        String result = classeEntidade.getName()
            .replace("org.networkmap.server.bean.",
            "org.networkmap.server.bean.dao.");
        result = result.concat("DAO");
        return result;
    }

    @Override
    public Object getDAO(Class<?> entityClass) {
        NetworkmapDao result = null;

        try {
           result = (NetworkmapDao) Class.forName(getDAOName(entityClass))
               .newInstance();
           result.setEntityManager(em);
        } catch (Exception e) {
           e.printStackTrace();
        }
        return result;
    }
}

There's a lot of EJB's that calls the getDAO method. And a lot of users of the app. I guess it may cause concurrent problems indeed.

I don't have a good expertise with that, but according some search on internet, it seems like there's no good practice on that code, considering that EntityManger is not thread safe. I'm stuck with this problem :(

The app uses the EclipseLink v2.4.2 API, running on a Weblogic 10.3.5 over a Solaris OS And there's only one persitent unit declared on persistence.xml .

Please someone help me.

Are you using the same EntityManager with different threads? If so, then don't do that.

Otherwise, please include the full exception stack trace.

What does, "result.setEntityManager(em);" do?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM