2011-09-22 24 views
15

Tengo una pregunta con respecto a JPA 2.0, Hibernate y "orphanRemoval".JPA 2.0/Hibernate y "orphanRemoval": el solo reemplazo de una entidad no elimina el anterior

En primer lugar mi configuración:

  • primavera 3.0.5.RELEASE
  • SprnigData JPA 1.0.1.RELEASE
  • Hibernate 3.5.2 de final
  • DBMS PostgreSQL 9.0:

Tengo dos clases de entidades bastante simples, "Usuario" y "Imagen de Avatar", Un "Usuario" tiene una "Imagen de Avatar", y así entre "Usuario" y "Imagen de Avatar" existe la relación ioneship.

En la categoría "Usuario", la propiedad tiene el siguiente aspecto:

// class "User" 
@OneToOne(cascade = CascadeType.ALL, fetch=FetchType.LAZY, orphanRemoval = true) 
private AvatarImage avatarImage; 

Eso quiere decir que, si la propiedad "avatarImage" se establece en cero, la referencia entre el "usuario" y "AvatarImage" es eliminado y el mecanismo "orphanRemoval" eliminará la "avatarImage" de la base de datos (corrígeme si me equivoco).

Así que cuando actualizo el "avatarImage" para un determinado usuario, actualmente tengo que escribir esto:

user.setAvatarImage(null); // First set it to null 
userRepository.save(user); // Now "orphanRemoval" will delete the old one 

user.setAvatarImage(theNewAvatarImage); 
userRepository.save(user); 

Así establecer la propiedad "avatarImage" primero en nulo, salvando el "usuario", y luego establece la nueva Imagen de Avatar "theNewAvatarImage", nuevamente guardando al usuario.

Esta es la única forma en que actualmente funciona para mí: el "huérfano Removimiento" eliminará el antiguo "avatarImage" al establecerlo en "nulo" y luego guardar al usuario.

Pero, yo habría pensado que este código también debería funcionar:

user.setAvatarImage(theNewAvatarImage); 
userRepository.save(user); 

Así Omito establecimiento de la "avatarImage" a "nulo", pero sólo la creación de "theNewAvatarImage", en sustitución del antiguo "avatarImage". Pero esto no funciona, el viejo AvatarImage no se elimina de la base de datos al comprometer la transacción.

¿Alguien sabe por qué el segundo código (simplemente reemplazando AvatarImage sin establecerlo antes como "nulo") no funciona?

Realmente aprecio la ayuda que puede ofrecer

Muchas gracias!

Respuesta

12

Esto se relaciona con las entradas de Hibernate JIRA HHH-5559 y HHH-6484. En general, Hibernate, a partir de hoy, requiere que establezca la referencia a nulo y limpie el contexto de persistencia, antes de proporcionar un nuevo valor a la relación (consulte el caso de prueba en HHH-6484); es solo en tal caso que Hibernate emite una declaración SQL DELETE, proporcionando una implementación interrumpida (en mi humilde opinión) para orphanRemoval.

En resumen, tendrá que esperar a que se reparen los errores, o escribir código para anular referencias y eliminar el contexto de persistencia, o usar un proveedor JPA que admita orphanRemoval de esta manera (EclipseLink 2.3.0 sí) .

1

A partir de la relación @OneToMany, esto está relacionado con el ticket de Hibernate JIRA HHH-6709. Por favor vote por estos para que reciba algo de atención.

Cuestiones relacionadas