Java.lang.IllegalStateException: несколько представлений одного и того же объекта с объектами @ManyToMany 3

У меня есть 3 лица с отношениями ManyToMany:

Роль

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

Разрешение 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<>();
}

Функциональность Entity:

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

Я сделал следующее:

  1. Я создал 3 функции:

    Functionality1, Functionality2, Functionality3
    
  2. Затем создано 2 разрешения:

    Permission1 with Functionality1, Functionality2
    
    Permission2 with Functionality2, Functionality3
    
  3. Затем создали роль:

    Role1 with Permission1 and Permission2 
    

Я получаю следующее исключение:

java.lang.IllegalStateException: несколько представлений одного и того же объекта [com.persistence.entity.admin.Functionality # 1] объединяются. Отдельно: [[email protected]]; Отдельно: [[email protected]]

Ответ 1

Исправлено, удалив CascadeType.MERGE на объекте Permission

Ответ 2

Правильным решением было бы перейти на спящий режим 4.2.15/4.3.6 или выше и добавить следующие строки в ваш persistence.xml:

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

Ответ 3

Проверьте свой метод equals и hashCode, убедитесь, что он согласован и правильно определен. Например, я скопировал и ошибочно вставил другой класс при вычислении hashCode, это заставило объект никогда не быть равным самому себе: (.

Ответ 4

Я столкнулся с той же проблемой и решил ее, добавив несколько конфигураций в файлы application.yaml.

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

См. Здесь. Как перенести новый объект, содержащий несколько идентичных экземпляров другого объекта, который не был загружен с помощью Spring Boot и JPA?

Ответ 5

В моем случае, перемещение операции выборки и сохранение операции в том же блоке @Transactional решило проблему.

Ответ 6

ошибка возникает, когда у нас есть несколько объектов того же времени в HashSet.Possible из-за неправильной хеш-функции. Хэш проверяет равенство объекта на основе хэш-функции между двумя объектами.

Способ отладки

Просто попробуйте напечатать hashset, вы увидите несколько объектов одного типа.

Решение::#

  • Используйте HashSet, определяя отношения от одного до многих.
  • Избегайте использования списков.
  • Убедитесь, что ваша функция хеша должна быть правильной.

Ответ 7

Не удалось добавить комментарий... низкая репутация :(

Но правильный ответ - тот, который задан пользователем @user1523177 - не уверен, почему он не помечен как принятый - fooobar.com/questions/451419/...

В принципе, это хэш и равный, который CascadeType.MERGE спящий режим вверх дном... исправить его и удалить CascadeType.MERGE - это не то, что вы хотите!

Ответ 8

@LazyCollection (LazyCollectionOption.FALSE

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

@JoinColumn (name = "translate_id")

Ответ 9

Я мог бы исправить это, заменив

cascade = CascadeType.All

с

casecade={CascadeType.PERSIST,CascadeType.REMOVE}

Ответ 10

Для Hibernate см. обходной путь здесь HHH-9106.

Ответ 11

Просто отметим, что я использую Hibernate Core 4.3.8 в приложении Spring MVC на основе Spring Core 4.1.6. Обходной путь:

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

Не работает для меня. Мне нужно было удалить CascadeType.MERGE, чтобы правильно заполнить @ManyToMany. Не уверен, что новые версии Hibernate исправили это.