【问题标题】:Caused by: org.hibernate.HibernateException: Found shared references to a collection引起:org.hibernate.HibernateException:找到对集合的共享引用
【发布时间】:2011-08-07 17:59:27
【问题描述】:

我正在运行这个异常:

Caused by: org.hibernate.HibernateException: Found shared references to a collection: path.Object.listObjects  

这是我的代码:
Object.java

protected List<ListedObject> listObjects ;  

....  
@OneToMany(cascade=CascadeType.ALL)
    @JoinTable(
            name = "object_list", 
            joinColumns=@JoinColumn(name="object_id", unique=true)  ,
            inverseJoinColumns=@JoinColumn(name="list_id")
    )
    public List<Annotation> getListObjects() {
        return listObjects;
    }
    public void setListObjects(List<ListedObject> listObjects){
        this.listObjects = listObjects;
    }

ListedObject.java

private Object object;  

...  

@ManyToOne(cascade=CascadeType.MERGE)
    @JoinTable(name = "object_list", 
            joinColumns=@JoinColumn(name="list_id"),
            inverseJoinColumns=@JoinColumn(name="object_id"))
    public MediaObject getObject() {
        return mediaObject;
    }

    public void setObject(Object object) {
        this.object = object;
    }  

请问有人可以帮我吗?
提前致谢!

EDIT异常开始的时间点:

ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");  

这来自:

5088 [main] WARN org.apache.commons.vfs.impl.StandardFileSystemManager - no protocol: VFSproviders.xml
java.net.MalformedURLException: no protocol: VFSproviders.xml  

我真的不知道它是为了什么,但VFSproviders.xml 在项目中,并且它拥有:

<?xml version="1.0" encoding="UTF-8"?>
<providers>
    <provider class-name="org.apache.commons.vfs.provider.zip.ZipFileProvider">
        <scheme name="zip"/>
    </provider>
    <extension-map extension="zip" scheme="zip"/>
    <mime-type-map mime-type="application/zip" scheme="zip"/>
    <provider class-name="org.apache.commons.vfs.provider.ftp.FtpFileProvider">
        <scheme name="ftp"/>
        <if-available class-name="org.apache.commons.net.ftp.FTPFile"/>
    </provider>
    <default-provider class-name="org.apache.commons.vfs.provider.local.DefaultLocalFileProvider"/>
</providers>

我完全迷失在这部分,任何帮助将不胜感激。谢谢

【问题讨论】:

  • 我之前已经回答过同样的问题:stackoverflow.com/questions/1692871/…
  • 公共列表中的注释是什么 getListObjects() { return listObjects; } ?
  • 我遇到了同样的异常,对我来说这是由于我的实体类的继承路径中有两次相同的属性引起的

标签: java hibernate


【解决方案1】:

这个问题过去已经回答过无数次了,但我遇到了一个新案例,它引发了与多线程相关的相同异常,并决定在此处发布,因为这是谷歌搜索异常时的最佳结果之一。

在我的例子中,我在 hibernate 中封装了一个简单的数据结构,然后封装在我自己的框架(几个管理器)中以供其他项目使用。管理器执行所有基本的 CRUD 操作以及一些查询和管理会话(或根据设置提供执行此操作的界面)。所有实体中都有一个字符串到字符串的映射,如果需要,它用于使用附加参数扩展对象。地图存储在单独的表中。在一个用例中,管理器在多个线程之间共享,并且仅用于检索对象。要检索的对象 id 来自同一个列表,如果线程同时需要相同的对象,则会抛出可怕的 Found 共享引用异常。

我理解背后的原理是这样的:

  1. 两个线程都查询/定位一个具有相同 ID 的对象
  2. Hibernate 进入数据库,获取两个相同的对象并开始构建它们
  3. 最终构建的对象是在两者之间共享的一张地图
  4. 在执行刷新或脏检查时,Hibernate 会发现问题并抛出异常

对我的所有查询和对象检索使用同步似乎已经解决了我的问题。我建议确保您与 Hibernate 会话的大部分交互是同步的,特别注意事务。希望这可以帮助任何遇到同样问题的人。

【讨论】:

  • 这听起来正是我遇到的问题。谢谢!
  • 正是我的问题。由于我使用 Java8,它是由使用 parallelStream 而不是流引起的(来自操纵我的实体的功能集合)。
  • 不应该在单独的会话中运行查询来解决问题吗?
  • @AndrasHatvani 抱歉,我无法再访问任何代码来验证这一点,但我认为在大多数情况下不共享一个会话在多个线程之间是正确的做法,并且应该可以解决这个问题,假设缓存在会话之间是分开的。
【解决方案2】:

您不应该在此联接的 OneToMany 端使用 @OneToMany 属性“mappedBy”而不是指定 JoinTable?

根据我的经验,您在关系的拥有方定义关系,并使用拥有方的“mappedBy”属性将其映射回来。

protected List<ListedObject> listObjects ;  

@OneToMany(cascade=CascadeType.ALL,mappedBy="Object")
public List<ListedObject> getListObjects() {
    return listObjects;
}
public void setListObjects(List<ListedObject> listObjects){
    this.listObjects = listObjects;
}

【讨论】:

  • 谢谢@Charles,也许你是对的,但这并不能解决我的问题。我遇到了同样的异常。
  • 在您已经将数据加载到内存或对其进行了一些操作之后会发生这种情况吗?通读休眠线程,这似乎指的是当您有一个分配给多个实体的托管集合时。每个实体都应该有自己的 Collection 对象,尽管其中包含的实体可能是重复的。
  • 这是在我将数据存储到数据库时发生的。 listObjects 的对象更多,我该如何区分它们?每次引用它时,它都是一个新数组,并且它应该位于每个包含它的表内的不同 collums 中。感谢您的评论
猜你喜欢
  • 2010-12-14
  • 2020-07-19
  • 2014-11-26
  • 2012-08-12
  • 1970-01-01
  • 2012-10-14
  • 1970-01-01
  • 1970-01-01
  • 2019-10-24
相关资源
最近更新 更多