Error Caused by: java.util.ConcurrentModificationException

Resolviendo el siguiente error en java para un sistema web con tecnología EJB 3.

Error:

java.util.ConcurrentModificationException
        at java.util.IdentityHashMap$IdentityHashMapIterator.nextIndex(IdentityHashMap.java:715)
        at java.util.IdentityHashMap$KeyIterator.next(IdentityHashMap.java:804)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.calculateChanges(UnitOfWorkImpl.java:567)
        at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.writeChanges(RepeatableWriteUnitOfWork.java:308)
        at org.eclipse.persistence.internal.jpa.EntityManagerImpl.flush(EntityManagerImpl.java:527)
        at org.eclipse.persistence.internal.jpa.EJBQueryImpl.performPreQueryFlush(EJBQueryImpl.java:1010)
        at org.eclipse.persistence.internal.jpa.EJBQueryImpl.executeReadQuery(EJBQueryImpl.java:344)
        at org.eclipse.persistence.internal.jpa.EJBQueryImpl.getResultList(EJBQueryImpl.java:568)

.....
Caused by: java.util.ConcurrentModificationException
        at java.util.IdentityHashMap$IdentityHashMapIterator.nextIndex(IdentityHashMap.java:715)
        at java.util.IdentityHashMap$KeyIterator.next(IdentityHashMap.java:804)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.calculateChanges(UnitOfWorkImpl.java:567)
        at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.writeChanges(RepeatableWriteUnitOfWork.java:308)
        at org.eclipse.persistence.internal.jpa.EntityManagerImpl.flush(EntityManagerImpl.java:527)
        at org.eclipse.persistence.internal.jpa.EJBQueryImpl.performPreQueryFlush(EJBQueryImpl.java:1010)
        at org.eclipse.persistence.internal.jpa.EJBQueryImpl.executeReadQuery(EJBQueryImpl.java:344)
        at org.eclipse.persistence.internal.jpa.EJBQueryImpl.getResultList(EJBQueryImpl.java:568)


Causa 1:

Esto puede ocurrir cuando se realiza una consulta por NamedQuery
List lista = em. createNamedQuery("Entity.findBy"). setParameter('param1',valor_param1)).getResultList();


Después se desea recorrer la lista y llenar alguna propiedad del entity que posea cascade, cascade = {CascadeType.MERGE, CascadeType.PERSIST}

Cuando se termina el método (termina la transacción) o se hace una consulta después de asignado un valor a una propiedad como la mencionada anteriormente, el EntityManager trata de sincronizar la nueva información ingresada con el objeto en cache (porque como fue consultado dentro del mismo método, los entitys dentro de la lista son Objetos Manejados) y si el valor ingresado fue un NULL, se lanza la excepción ConcurrentModificationException


Solución:

La solución de este error se puede hacer de dos formas diferentes:

Primera Forma.

Cuando se recorra la lista, la información deseada se debe almacenar en un objeto nuevo y asignándole los datos, pero nunca modificar el objeto manejado.

De esta forma no se cambian los datos almacenados en la BD de los objetos manejados.



Segunda Forma.

Cuando se recorra la lista, la información deseada se debe validar que sea diferente de null, antes de asignarla para que no se presente el problema.

De esta forma SE cambian los datos almacenados en la BD de los objetos manejados.

Comentarios