代码之家  ›  专栏  ›  技术社区  ›  nightingale2k1

找到对集合org.hibernate.hibernateexception的共享引用

  •  48
  • nightingale2k1  · 技术社区  · 15 年前

    我收到错误消息:

    错误:找到对集合的共享引用:Person.RelatedPersons

    当我试图执行 addToRelatedPersons(anotherPerson) :

    person.addToRelatedPersons(anotherPerson);
    anotherPerson.addToRelatedPersons(person);
    
    anotherPerson.save();
    person.save();
    

    我的领域:

    Person {
    
     static hasMany = [relatedPersons:Person];
    
    }
    

    知道为什么会这样吗?

    8 回复  |  直到 6 年前
        1
  •  55
  •   Vlastimil Ovčáčík    9 年前

    当您尝试保持多个实体实例共享时,Hibernate会显示此错误。 相同的 集合引用(即集合标识与集合相等性形成对比)。

    注意它的意思是一样的 收集 ,不是集合元素-换句话说 relatedPersons 两者兼而有之 person anotherPerson 必须相同。可能是在加载实体之后重置了该集合?或者您已经用同一个集合实例初始化了这两个引用?

        2
  •  45
  •   Rubens Mariuzzo Salakar    9 年前

    我也有同样的问题。在我的例子中,问题是有人使用beanutils将一个实体的属性复制到另一个实体,所以我们最终得到了两个引用同一集合的实体。

    鉴于我花了一些时间调查这个问题,我建议使用以下检查表:

    • 寻找类似 entity1.setCollection(entity2.getCollection()) getCollection 返回对集合的内部引用(如果getCollection()返回集合的新实例,则无需担心)。

    • 看,如果 clone() 已正确实施。

    • 寻找 BeanUtils.copyProperties(entity1, entity2) .

        3
  •  4
  •   Mirimas    9 年前

    实践说明。如果试图保存对象,例如:

    Set<Folder> folders = message.getFolders();
       folders.remove(inputFolder);
       folders.add(trashFolder);
       message.setFiles(folders);
    MESSAGESDAO.getMessageDAO().save(message);
    

    不需要将更新的对象设置为父对象:

    message.setFiles(folders);
    

    简单地将父对象保存为:

    Set<Folder> folders = message.getFolders();
       folders.remove(inputFolder);
       folders.add(trashFolder);
       // Not set updated object here
    MESSAGESDAO.getMessageDAO().save(message);
    
        4
  •  2
  •   John Lopez    8 年前

    在我的例子中,我从其他类复制和粘贴代码,所以我没有注意到getter代码写得不好:

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "credito")
    public Set getConceptoses() {
        return this.letrases;
    }
    
    public void setConceptoses(Set conceptoses) {
        this.conceptoses = conceptoses;
    }
    

    所有参考文献 概念 但是如果你看球台上说 脂肪酶

        5
  •  2
  •   Diego87    8 年前

    在线阅读此错误的原因也可能是 冬眠虫 ,作为 解决办法 它似乎有效,它是要放一个:

    session.clear()
    

    必须在获取数据之后、提交和关闭之前清除,请参见示例:

    //getting data
    SrReq sr = (SrReq) crit.uniqueResult();
    SrSalesDetailDTO dt=SrSalesDetailMapper.INSTANCE.map(sr);
    //CLEAR            
    session.clear();
    //close session
    session.getTransaction().commit();
    session.close();
    return dt;
    

    我使用这个解决方案来选择数据库,更新或插入,我不知道这个解决方案是否有效,或者是否会导致问题。

    我的问题等于100%: http://www.progtown.com/topic128073-hibernate-many-to-many-on-two-tables.html

        6
  •  1
  •   SkyWalker    6 年前

    我也有同样的问题,有人用过 BeanUtils.copyProperties(source, target) . 这里,源和目标都使用与属性相同的集合。

    所以我只是用了下面的深度拷贝……

    How to Clone Collection in Java - Deep copy of ArrayList and HashSet

        7
  •  0
  •   Kalle Richter    7 年前

    我的申请中也遇到了类似的例外。在查看stacktrace之后,很明显在 FlushEntityEventListener 类。

    在休眠4.3.7中 MSLocalSessionFactory bean不再支持 eventListeners 属性。因此,必须从各个休眠会话bean显式获取服务注册表,然后设置所需的自定义事件侦听器。

    在添加自定义事件侦听器的过程中,我们需要确保从相应的休眠会话中删除相应的默认事件侦听器。

    如果未删除默认事件侦听器,则会出现针对同一事件注册的两个事件侦听器。在这种情况下,当对这些侦听器进行迭代时,对于第一个侦听器,会话中的任何集合都将标记为已到达,而对第二个侦听器处理相同的集合时,将引发此休眠异常。

    因此,请确保在注册自定义侦听器时,从注册表中删除相应的默认侦听器。

        8
  •  -1
  •   fmw42    6 年前

    考虑一个实体:

    public class Foo{
    private<user> user;
    /* with getters and setters */
    }
    

    并考虑一个业务逻辑类:

    class Foo1{
    List<User> user = new ArrayList<>();
    user = foo.getUser();
    }
    

    这里是用户和 foo.getUser() 共享同一引用。但是保存这两个引用会产生冲突。

    正确的用法应该是:

    class Foo1 {
    List<User> user = new ArrayList<>();
    user.addAll(foo.getUser);
    }
    

    这样就避免了冲突。