Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

java

hibernate

I am running this exception:

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

This is my code:
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;
    }  

Could anybody help me on this, please??
Thanks in advance!

EDIT the point when the exception starts:

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

And this comes from:

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

I don't really know what for is it, but VFSproviders.xml is in the project, and it holds:

<?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>

I am completely lost in this part, any help would be really appreciated. Thanks

like image 899
Blanca Hdez Avatar asked Apr 18 '11 09:04

Blanca Hdez


2 Answers

This question has been answered numerous times in the past, but I have encountered a new case that raises the same exception related to multithreading and decided to post here because this is one of the top results when googling for the exception.

In my case I have wrapped a simple data structure in hibernate and then wrapped in my own framework (a couple of managers) to be used by other projects. The managers perform all the basic CRUD operations plus a few queries and manage sessions (or provide an interface to do so, based on settings). All the entities have a String to String map in them and it is used to extend the objects with additional parameters if necessary. The map is stored in a separate table. In one use case a manager is shared between several threads, and is used just to retrieve objects. The object ids to retrieve come from the same list, and if the threads require the same object at the same time, the dreaded Found shared references exception is thrown.

I understand that the principle behind is something like this:

  1. Both threads query/locate an object, both with the same ID
  2. Hibernate goes to the DB, gets two identical objects and starts building them up
  3. The objects end up being built with one map shared between the two
  4. Upon doing a flush or a dirty check Hibernate discovers the problem and throws the exception

Using synchronized on all of my queries and object retrievals seems to have solved the problem for me. I would suggest making sure that most of your interactions with Hibernate sessions are synchronized, being especially careful about transactions. Hope this helps anybody stuck with the same problem.

like image 155
Mike Demenok Avatar answered Nov 15 '22 12:11

Mike Demenok


Shouldn't you be using the @OneToMany attribute "mappedBy" on the OneToMany side of this join instead of specifying the JoinTable?

In my experience, you define the relation on the owning side of the relation, and map it back using the "mappedBy" attribute from the owned side.

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;
}
like image 42
SplinterReality Avatar answered Nov 15 '22 13:11

SplinterReality