java.lang.IllegalStateException:具有@ManyToMany 3实体的同一实体的多个表示形式

时间:2014-10-27 15:52:42

标签: java hibernate jpa jpa-2.0 ejb-3.0

我有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个权限:

    a. Permission 1 with functionality1, functionality2.
    
    b. Permission 2 with functionality2, functionality3.
    
  3. 然后在创建角色时:

    Role 1 with Permission1 and Permission2 iam getting following exception
    
      

    java.lang.IllegalStateException:正在合并同一实体[com.persistence.entity.admin.Functionality#1]的多个表示。分离:[com.persistence.entity.admin.Functionality@4729256a];分离:[com.persistence.entity.admin.Functionality@56ed25db]

12 个答案:

答案 0 :(得分:29)

通过删除Permission entity

上的CascadeType.MERGE来解决此问题

答案 1 :(得分:10)

检查你的equals和hashCode方法,确保它是一致的并且正确定义。例如,我在计算hashCode时复制并错误地粘贴了另一个类,这导致对象永远不会与自身相等:(。

答案 2 :(得分:3)

我也遇到了同样的问题,并通过在application.yaml文件中添加一些配置来解决了这个问题。

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

在这里How to persist a new entity containing multiple identical instances of another unpersisted entity with spring-boot and JPA?

答案 3 :(得分:1)

就像其他人基于HHH-9106来回答一样,但是,由于我将Spring Boot与基于Java的注释一起使用,因此我不得不在application.properties中使用以下内容:

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

答案 4 :(得分:0)

在我的情况下,在同一个@Transactional块中移动获取操作和保存操作解决了这个问题。

答案 5 :(得分:0)

当我们在HashSet中有多个对象同时发生错误。由于哈希函数不正确,可能发生。Hashset根据两个对象之间的哈希函数检查对象的相等性。

调试方式

只需尝试打印哈希集,您将看到多个相同类型的对象。

解决方案::#

  • 在定义一对多关系时使用HashSet。
  • 避免使用列表。
  • 确保您的哈希函数正确无误。

答案 6 :(得分:0)

无法添加评论...信誉低下:(

但是正确的答案是@ user1523177给出的答案-不知道为什么未将其标记为接受的答案-https://stackoverflow.com/a/34420512/6914827

基本上,是哈希值和等于值将休眠模式颠倒了...对其进行修复,然后删除CascadeType.MERGE并不是您想要的!

答案 7 :(得分:0)

@LazyCollection(LazyCollectionOption.FALSE

@OneToMany(级联= CascadeType.ALL,orphanRemoval = true)

@JoinColumn(name =“ translate_id”)

答案 8 :(得分:0)

我可以通过替换

进行修复
cascade = CascadeType.All

使用

casecade={CascadeType.PERSIST,CascadeType.REMOVE}

答案 9 :(得分:0)

我通过删除您的情况下的cascade = CascadeType.ALLcascade = {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<>();

答案 10 :(得分:-1)

对于Hibernate,请参阅此处的解决方法HHH-9106

答案 11 :(得分:-1)

请注意,我在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修复此问题。