web-dev-qa-db-ja.com

java.lang.IllegalStateException:@ManyToMany 3エンティティを持つ同じエンティティの複数の表現

ManyToMany関係を持つ3つのエンティティがあります。

役割エンティティ:

@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]

23
user1188867

PermissionエンティティのCascadeType.MERGEを削除して修正しました

32
user1188867

正しい解決策は、hibernate 4.2.15/4.3.6以降にアップグレードし、persistence.xmlに次の行を追加することです。

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

23
Suraj Menon

EqualsメソッドとhashCodeメソッドを確認し、一貫性があり、正しく定義されていることを確認してください。たとえば、hashCodeを計算するときに別のクラスをコピーして誤って貼り付けたため、オブジェクトがそれ自身と等しくなることはありませんでした:(.

12
user1523177

コメントを追加できませんでした...低評価:(

しかし、正しい答えは@ user1523177によるものです-なぜそれが受け入れられたものとしてマークされていないのか分かりません- https://stackoverflow.com/a/34420512/6914827

基本的に、休止状態を上下逆にするのはハッシュとイコールです...それを修正し、CascadeType.MERGEを削除することはあなたが望むものではありません!

0
Ken007

ハッシュ関数が正しくないため、HashSet.Possibleに同じ時間の複数のオブジェクトがある場合、エラーが発生します。ハッシュセットは、2つのオブジェクト間のハッシュ関数に基づいてオブジェクトの等価性をチェックします。

デバッグする方法

ハッシュセットを印刷しようとすると、同じタイプの複数のオブジェクトが表示されます。

溶液::#

  • HashSetを使用して、1対多の関係を定義します。
  • リストの使用は避けてください。
  • ハッシュ関数が正しいことを確認してください。
0
razi

私の場合、同じ@Transactionalブロックでフェッチ操作と保存操作を移動すると、問題が解決しました。

0

交換することで修正できます

cascade = CascadeType.All

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