java.lang.IllegalStateException: Multiple representations of the same entity with @ManyToMany 3 entities

89,812

Solution 1

Fixed it by removing CascadeType.MERGE on Permission entity

Solution 2

The correct solution would have been to upgrade to hibernate 4.2.15 / 4.3.6 or above and add the following lines to your persistence.xml:

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

Solution 3

Check your equals and hashCode method, ensure that it is consistent and correctly defined. For example I had copied and mistakenly pasted another-class when computing hashCode, this caused the object never to be equal with itself :(.

Solution 4

Like others who based their answers on HHH-9106 but, because I'm using Spring Boot with Java-based annotation, I had to use the following in application.properties:

spring.jpa.properties.hibernate.event.merge.entity_copy_observer=allow

Solution 5

I ran into the same problem too and solved it by add a few configs in application.yaml files.

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

See it here How to persist a new entity containing multiple identical instances of another unpersisted entity with spring-boot and JPA?

Share:
89,812
user1188867
Author by

user1188867

Updated on July 05, 2022

Comments

  • user1188867
    user1188867 almost 2 years

    I have 3 entities with ManyToMany relationships:

    Role Entity:

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

    Permission Entity:

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

    Functionality Entity:

    @Entity
    public class Functionality {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Integer id;
        private String name;
    }
    

    I did the following:

    1. I have created 3 functionalities:

      Functionality1, Functionality2, Functionality3
      
    2. Then created 2 permissions:

      Permission1 with Functionality1, Functionality2
      
      Permission2 with Functionality2, Functionality3
      
    3. Then created a role:

      Role1 with Permission1 and Permission2 
      

    I am getting the following exception:

    java.lang.IllegalStateException: Multiple representations of the same entity [com.persistence.entity.admin.Functionality#1] are being merged. Detached: [com.persistence.entity.admin.Functionality@4729256a]; Detached: [com.persistence.entity.admin.Functionality@56ed25db]

  • ByteHamster
    ByteHamster about 9 years
    Please quote the most relevant part of the link, in case the target site is unreachable or goes permanently offline. See How do I write a good answer.
  • VHS
    VHS over 7 years
    This property applies to the entire persistent context and should only be used for testing purposes. If you set it to "allow" or "log", Hibernate will proceed with merging both the detached entities sequentially. However the order of the merge is not defined. So this can cause accidental data corruption. The correct solution is to fix the entity relationship.
  • Stephan
    Stephan over 7 years
    Or in case, my network blocks some CSS files, the site is completely unreadable.
  • Mate Šimović
    Mate Šimović almost 7 years
    Try using Hibernate cascade annotations instead of JPA annotations. Eg.,@Cascade(CascadeType.SAVE_UPDATE) would replace {CascadeType.PERSIST,CascadeType.MERGE }. Check this article: JPA & Hibernate annotation common mistake
  • Aleksandar
    Aleksandar almost 7 years
    Great answer! Thank You! IntelliJ has a procedure for generating equals and hashCode, You can check it out on their website.
  • SP5RFD
    SP5RFD almost 7 years
    This helped! I'm using Lombok's Data annotation to generate all my additional methods, when changed to Getter Setter instead of @Data the problem has gone. Thank you.
  • El Mac
    El Mac almost 6 years
    What effect does this have if I want to merge existing entities? What happens when I remove CascadeType.MERGE?
  • El Mac
    El Mac almost 6 years
    @VHS can you explain what happens if I remove CascadeType.MERGE? I see it as the answer everywhere, but I bet it is a breaking change with side effects.
  • securecurve
    securecurve almost 6 years
    Yes, having the same question, what happens when we remove the MERGE cascade?
  • securecurve
    securecurve almost 6 years
    I think I know why. It means if the entity is merged, the related entity is merged too, which is not the case in this situation, because we only want to create a new Role, but we don't want to create/update a Permission.
  • udoline
    udoline about 5 years
    Works for me ... :D (Spring Boot 1.4.1.RELEASE)
  • GuiRitter
    GuiRitter over 4 years
    The link is about the hibernate.event.merge.entity_copy_observer property, which is already (at the time of this writing) covered by other answers.
  • Kareem Jeiroudi
    Kareem Jeiroudi over 3 years
    What if I'm not using Hibernate?
  • Kareem Jeiroudi
    Kareem Jeiroudi over 3 years
    equals and hashCode of the parent entity or the detached entity?
  • marcotama
    marcotama about 3 years
    @ElMac without CascadeType.MERGE, if you save an object that has a reference to another, you need to manually also store that other object; with CascadeType.MERGE, on the other hand, Hibernate does it for you automatically. So you are correct, this might cause other problems.
  • Daniel Jipa
    Daniel Jipa almost 3 years
    never do CascadeType.ALL on ManyToMany