java.lang.IllegalStateException: Representaciones mĂșltiples de la misma entidad con @ManyToMany 3 entidades
hibernate jpa (10)
Tengo 3 entidades con relaciones ManyToMany como a continuación:
Entidad de rol:
@Entity
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer roleID;
private String roleName;
private String description;
@ManyToMany(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}, fetch = FetchType.EAGER)
@JoinTable(name = "role_permission", joinColumns = {@JoinColumn(name = "role_id")}, inverseJoinColumns = {@JoinColumn(name = "permission_id")})
private Set<Permission> permissions = new LinkedHashSet<Permission>();
Entidad de permisos:
@Entity
public class Permission {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int permissionID;
private String permissionName;
private String description;
@ManyToMany(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}, fetch = FetchType.EAGER)
@JoinTable(name = "permission_functionality", joinColumns = {@JoinColumn(name = "permission_id")}, inverseJoinColumns = {@JoinColumn(name = "functionality_id")})
private Set<Functionality> functionalities = new LinkedHashSet<>();
Funcionalidad Entidad:
@Entity
public class Functionality {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
Hice lo siguiente:
He creado 3 funcionalidades.
functionality1, functionality2, functionality3
Luego creó 2 permisos como:
a. Permission 1 with functionality1, functionality2. b. Permission 2 with functionality2, functionality3.
Luego mientras creas un rol como:
Role 1 with Permission1 and Permission2 iam getting following exception
java.lang.IllegalStateException: Se están fusionando múltiples representaciones de la misma entidad [com.persistence.entity.admin.Functionality # 1]. Separado: [com.persistence.entity.admin.Functionality@4729256a]; Separado: [com.persistence.entity.admin.Functionality@56ed25db]
En mi caso, mover la operación de recuperación y la operación de guardar en el mismo bloque @Transactional resolvió el problema.
La solución correcta habría sido actualizar a hibernación 4.2.15 / 4.3.6 o superior y agregar las siguientes líneas a su persistence.xml:
<property name="hibernate.event.merge.entity_copy_observer" value="allow"/>
No se pudo agregar un comentario ... baja reputación :(
Pero la respuesta correcta es la de @ user1523177; no estoy seguro de por qué no está marcado como aceptado, https://.com/a/34420512/6914827
Básicamente, es el hash y es lo que da la vuelta a la hibernación ... CascadeType.MERGE
y eliminando el CascadeType.MERGE
no es lo que quieres.
Para Hibernate ver la solución aquí HHH-9106 .
Se corrigió eliminando CascadeType.MERGE en la entidad de permiso
Solo una nota para decir que estoy usando Hibernate Core 4.3.8 en una aplicación Spring MVC, basado en Spring Core 4.1.6. La solución:
<property name="hibernate.event.merge.entity_copy_observer" value="allow"/>
No funcionó para mí. Necesitaba eliminar el CascadeType.MERGE para completar correctamente un @ManyToMany. No estoy seguro si las nuevas versiones de Hibernate han solucionado esto.
También encontré el mismo problema y lo resolví agregando algunas configuraciones en application.yaml
archivos de application.yaml
.
jpa:
properties:
hibernate:
enable_lazy_load_no_trans: true
event:
merge:
entity_copy_observer: allow
Véalo aquí. ¿Cómo persistir una nueva entidad que contiene múltiples instancias idénticas de otra entidad sin par con Spring-boot y JPA?
Verifique sus métodos equals y hashCode, asegúrese de que sean coherentes y estén correctamente definidos. Por ejemplo, cuando copié un código hash, copié y pegué por error otra clase, esto hizo que el objeto nunca fuera igual a sí mismo :(.
el error se produce cuando tenemos varios objetos del mismo tiempo en HashSet.Possible debido a una función de hash incorrecta. Hashset verifica la igualdad de los objetos sobre la base de la función de hash entre dos objetos.
Forma de depurar
Solo intente imprimir hashset verá varios objetos del mismo tipo.
Solución::#
- Use HashSet mientras define una o muchas relaciones.
- Evite utilizar listas.
- Asegúrate de que tu función hash sea correcta.
@LazyCollection (LazyCollectionOption.FALSE
@OneToMany (cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn (name = "translate_id")