2010-08-24 25 views
14

Duplicar posibles:
Hibernate Error: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the sessionHibernate: objeto diferente con el mismo valor de identificador ya estaba asociado con la sesión

cuando uso el DAO.update (UserBean), session.SaveOrUpdate(e); lanzar el Excepción: el objeto diferente con el mismo valor de identificador ya estaba asociado con la sesión

la función es como la siguiente:

public E save(E e) { 
    Session session = null; 
    try { 
     session = sessionFactory.openSession(); 
     log.debug("session="+session.hashCode()+" save "+e); 
     session.SaveOrUpdate(e); //here throws exception 
     session.flush(); 
    } 
    catch (Exception e1) { 
     log.err("Cannot open hibernate session "+ e1.getMessage()+" cause : "+e1.getCause()); 
     e1.printStackTrace(); 
    } 
    finally { if (session != null) session.close(); session = null;} 
    return e ; 
} 

la UserBean es una instancia de la clase UserBean

public class UserBean{ 
    private List<GroupBean> groups = new ArrayList<GroupBean>(); 
    private List<RoleBean> roles = new ArrayList<RoleBean>(); 
} 

public class GroupBean{ 
private List<RoleBean> roles = new ArrayList<RoleBean>(); 
} 

cada groupbean tiene una lista de funciones, que no se alteran.

la base de datos, el grupo y el papel es de muchos a muchos mapeo,

por ejemplo,

tenemos una groupbean # 1, es rolebean papeles: # 1, # 2 rolebean;

groupbean # 2, cuyas funciones son rolebean # 1.

ahora crear una nueva UserBean # 1, es grupos es groupbean # 1 y si quiero añadir el rolebean # 1 a UserBean # 1, se produce la excepción como la descripta título

Miro la server.log, y parece que cuando DAO.save usuario, la orden es saveOrUpdate:

userbean#1 
|---|-----------***userbean.groups 
|  |  groupbean#1 
|  |   groupbean.roles 
|  |    rolebean#1 # save relebean#1 the first time 
|  |    ---done rolebean#1 
|  |   ------done all rolebeans of group.roles 
|  |  ---done groupbean#1 
|  |-----------done all groupbeans of userbean.groups 
|---|-----------***userbean.roles 
    |  rolebean#1   # save rolebean#1 the second time, and throws exception here! 
    |  ----done rolebean#1 
    |  ..... 
    |-----------done all rolebeans of userbean.roles 

la causa de la excepción es rolebean # 1 se ha salvado dos veces en una sesión, y su identidad es la misma .

En la función Guardar (Ee), Si uso

session.merge(e); 

reemplazar

session.SaveOrUpdate(e); 

no lanzará una excepción, pero el rolebean # 1 no está assocaited a UserBean # 1

alguien puede dar algunas sugerencias al respecto?

Respuesta

27

Sería más fácil identificar la causa exacta si podemos ver el código donde está asignando el rol bean tanto al usuario como al grupo.

En general, lo que nos dice la excepción es que hay dos versiones de ese rol bean (dos instancias). El primero se actualiza, luego Hibernate golpea el segundo y reconoce que es el mismo identificador pero una versión diferente del rol.

Hibernate no está seguro de cuál es la correcta, y en saveOrUpdate, arroja una excepción para hacerle saber.

El contrato de Merge funciona de manera diferente, en el sentido de que se suponía que tenía que guardarlo de nuevo (es decir, fusionar todos mis cambios), y así volverá a conectar la segunda versión, fusionará todos los cambios y guardará las actualizaciones.

He escrito sobre SaveOrUpdate vs Merge con más detalles para explicar lo que está pasando.

Si desea seguir con SaveOrUpdate, necesitará averiguar qué está haciendo en la tarea que está causando que una instancia diferente de la función se asigne a la colección de funciones del usuario frente a los grupos.

De lo contrario, si los efectos de la fusión funcionan para usted (que está en línea con el estándar JPA), entonces úselos.

Cuestiones relacionadas