web-dev-qa-db-fra.com

java.lang.IllegalStateException: plusieurs représentations de la même entité avec les entités @ManyToMany 3

J'ai 3 entités avec des relations ManyToMany comme ci-dessous:

Entité de rôle:

    @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>();

Autorisation:

    @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<>();

Entité de fonctionnalité:

    @Entity
public class Functionality {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;

J'ai fait ce qui suit:

  1. J'ai créé 3 fonctionnalités. 

    functionality1, functionality2, functionality3
    
  2. Puis créé 2 autorisations en tant que:

    a. Permission 1 with functionality1, functionality2.
    
    b. Permission 2 with functionality2, functionality3.
    
  3. Puis en créant un rôle en tant que:

    Role 1 with Permission1 and Permission2 iam getting following exception
    

    Java.lang.IllegalStateException: plusieurs représentations de la même entité [com.persistence.entity.admin.Functionality # 1] sont en cours de fusion. Détaché: [com.persistence.entity.admin.Functionality@4729256a]; Détaché: [com.persistence.entity.admin.Functionality@56ed25db]

19
user1188867

Corrigé en supprimant CascadeType.MERGE sur l'entité Permission

28
user1188867

La bonne solution aurait été de passer à la version 4.2.15/4.3.6 ou supérieure et d’ajouter les lignes suivantes à votre fichier persistence.xml:

<property name="hibernate.event.merge.entity_copy_observer" value="allow"/> 

20
Suraj Menon

Vérifiez votre méthode equals et hashCode, assurez-vous qu'elle est cohérente et correctement définie. Par exemple, j'avais copié et collé par erreur une autre classe lors du calcul de hashCode. Cela faisait que l'objet n'était jamais égal à lui-même :(.

8
user1523177

J'ai rencontré le même problème aussi et l'a résolu en ajoutant quelques configs dans des fichiers application.yaml.

  jpa:
    properties:
      hibernate:
        enable_lazy_load_no_trans: true
        event:
          merge:
            entity_copy_observer: allow

Voir ici Comment conserver une nouvelle entité contenant plusieurs instances identiques d'une autre entité non-persistée avec spring-boot et JPA

1
W.Man

Impossible d'ajouter un commentaire ... faible réputation :(

Mais la bonne réponse est celle de @ user1523177 - ne sait pas pourquoi elle n'est pas marquée comme acceptée - https://stackoverflow.com/a/34420512/6914827

En gros, c’est le hachage et l’égal à égal qui met l’hibernation à l'envers ... corrigez-le et supprimer le CascadeType.MERGE n’est pas ce que vous voulez!

0
Ken007

une erreur se produit lorsque nous avons plusieurs objets du même temps dans HashSet.Possible en raison d'une fonction de hachage incorrecte. Hashset vérifie l'égalité de l'objet sur la base de la fonction de hachage entre deux objets.

Manière de déboguer

Essayez simplement d’imprimer hashset, vous verrez plusieurs objets du même type.

Solution::#

  • Utilisez HashSet lorsque vous définissez une à plusieurs relations.
  • Évitez d’utiliser des listes. 
  • Assurez-vous que votre fonction de hachage doit être correcte.
0
razi

Dans mon cas, le déplacement des opérations d'extraction et d'enregistrement dans le même bloc @Transactional a résolu le problème.

0

Je pourrais le réparer en remplaçant 

cascade = CascadeType.All

avec

casecade={CascadeType.PERSIST,CascadeType.REMOVE}
0
Arul Rozario

@LazyCollection (LazyCollectionOption.FALSE  

@OneToMany (cascade = CascadeType.ALL, orphanRemoval = true)

@JoinColumn (name = "translate_id")

0
Paul Linux