簡體   English   中英

java.lang.IllegalStateException:具有@ManyToMany 3 個實體的同一實體的多個表示

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

我有 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
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
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] 的多個表示。 分離:[com.persistence.entity.admin.Functionality@4729256a]; 分離:[com.persistence.entity.admin.Functionality@56ed25db]

通過刪除權限實體上的 CascadeType.MERGE 修復它

正確的解決方案是升級到 hibernate 4.2.15 / 4.3.6 或更高版本,並將以下幾行添加到您的 persistence.xml 中:

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

檢查您的 equals 和 hashCode 方法,確保它是一致且正確定義的。 例如,我在計算 hashCode 時復制並錯誤地粘貼了另一個類,這導致對象永遠不會與自身相等:(。

就像其他人的答案基於HHH-9106 一樣,但是,因為我使用的是帶有基於 Java 的注釋的 Spring Boot,所以我不得不在application.properties使用以下內容:

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

我也遇到了同樣的問題,並通過在application.yaml文件中添加一些配置來解決它。

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

在此處查看如何使用 spring-boot 和 JPA 持久化包含另一個非持久化實體的多個相同實例的新實體?

我可以通過更換來修復它

cascade = CascadeType.All

casecade={CascadeType.PERSIST,CascadeType.REMOVE}

對於 Hibernate,請參閱此處的解決方法HHH-9106

就我而言,在同一個 @Transactional 塊中移動 fetch 操作和 save 操作解決了這個問題。

當我們在 HashSet 中同時有多個對象時會發生錯誤。可能由於不正確的哈希函數。Hashset 根據兩個對象之間的哈希函數檢查對象的相等性。

調試方式

只需嘗試打印哈希集,您就會看到多個相同類型的對象。

解決方案::#

  • 在定義一對多關系時使用 HashSet。
  • 避免使用列表。
  • 確保您的哈希函數應該是正確的。
**@LazyCollection(LazyCollectionOption.FALSE** 

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

@JoinColumn(name = "translate_id")

我通過在你的情況下刪除cascade = CascadeType.ALL解決了這個問題( cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}

我的代碼來源:

@ManyToMany(fetch=FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(
    name = "link_module_parcour",
    joinColumns = {@JoinColumn(name = "module_id", referencedColumnName = "id")},
    inverseJoinColumns = {@JoinColumn(name = "parcour_id", referencedColumnName = "id")})
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@BatchSize(size = 20)
private Set<Parcour> parcours = new HashSet<>();

@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(
    name = "link_module_parcour",
    joinColumns = {@JoinColumn(name = "module_id", referencedColumnName = "id")},
    inverseJoinColumns = {@JoinColumn(name = "parcour_id", referencedColumnName = "id")})
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@BatchSize(size = 20)
private Set<Parcour> parcours = new HashSet<>();

如果您刪除級聯合並,您將無法在更新父實體時更新實體。 如果您不想更新子項,則情況是正確的,但是如果您想在更新父項時更新子項,刪除合並只會不顯示錯誤,但問題仍然存在。

我發生了什么:我遇到了同樣的異常,但我需要 Cascade.merge。 搜索后,我發現我在第一次創建實體時使用的一些值已更新並從代碼中刪除,但在數據庫中,它們仍然存在,並且在從數據庫中刪除它們時也按預期工作。

澄清一下:假設我有一個枚舉('ACTIVE','NOT_ACTIVE','SUSPENDED')並且使用這個枚舉的字段是關鍵,當更新代碼並刪除 NOT_ACTIVE 時,我們應該用新的改變數據庫表值枚舉('活動','暫停')

我遇到了類似的問題,當我用{CascadeType.persist, CascadeType.remove}替換CascadeType.All時問題得到解決。

讓我知道它是否有效。

只是說明我在 Spring MVC 應用程序中使用 Hibernate Core 4.3.8,基於 Spring Core 4.1.6。 解決方法:

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

沒有為我工作。 我需要刪除 CascadeType.MERGE 以正確填充 @ManyToMany。 不確定較新版本的 Hibernate 是否已修復此問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM