-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 
Author Message
 Post subject: "found shared references to a collection" with ejb
PostPosted: Sun Nov 27, 2005 9:51 am 
Newbie

Joined: Wed Jan 07, 2004 12:02 pm
Posts: 15
Location: Herne, Germany
I get a "found shared references to a collection" exception and I can't see that
any of the usual explanations (assigning members of an entity's collection to
another entity's collection) fit to my situation. Now I succeeded in reducing
my code to a very simple example that reproduces this exception. I think that it
is very similar to the problem Antoine Oberlaender describes
(http://jira.jboss.com/jira/browse/EJBTHREE-348) even if I don't use an
application server to execute the code. At least I have a circular
reference in my model like Antoine.

I'd be happy if anyone could help me with this. So this is the example:

Code:
          rel
  Group n --- 1 User
    m             ^
    |             | inh
    |  rel        |
    --------- n Member

rel stands for relation (association)
inh stands for inheritance


The exception is thrown after Member objects have successfully been created and
then have been read from the database. After the last Member object was read the
transaction is committed but this fails.

Here is the code:

Group
Code:
import java.util.Set;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;

import java.io.Serializable;

import javax.persistence.Entity;

import javax.persistence.GeneratorType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;


@Entity
@Table(name = "Group")

@Inheritance(strategy = InheritanceType.JOINED)
public class Group
   implements Serializable
{
   @Id(generate = GeneratorType.AUTO)
   private long id;

   private String name;

   @ManyToMany
   @JoinTable(
      table              = @Table(name = "Group___Member"),
      joinColumns        = { @JoinColumn(name = "idGroup")},
      inverseJoinColumns = { @JoinColumn(name = "idMember")})
   private Set<Member> members;

   @ManyToOne
   @JoinColumn(name = "idRelatedUserUser")
   private User user;

   public Group()
   {
  }

   @Id(generate = GeneratorType.AUTO)
   public long getId()
   {
      return this.id;
   }

   protected void setId(long id)
   {
      this.id = id;
   }

   @ManyToMany
   @JoinTable(
      table = @Table(name = "Group___Member"),
      joinColumns = { @JoinColumn(name = "idGroup")},
      inverseJoinColumns = { @JoinColumn(name = "idMember")})
   public Set<Member> getMembers()
   {
      return this.members;
   }

   public void setMembers(Set<Member> members)
   {
      this.members = members;
   }

   public String getName()
   {
      return this.name;
   }

   public void setName(String name)
   {
      this.name = name;
   }

   @ManyToOne
   @JoinColumn(name = "idRelatedUserUser")
   public User getUser()
   {
      return this.user;
   }

   public void setUser(User user)
   {
      this.user = user;
   }

   public boolean equalsIgnorePrimaryKey(Group other)
   {
      if (!(this.getName().equals(other.getName())))
      {
         return false;
      }

      return true;
   }

   public boolean equals(Group other)
   {
      if (other == null)
      {
         return false;
      }

      if (!(this.getId() == other.getId()))
      {
         return false;
      }

      return this.equalsIgnorePrimaryKey(other);
   }

   @Override
   public String toString()
   {
      StringBuffer result = new StringBuffer();

      result.append("id: [" + this.getId() + "]").append(
            "\nname: [" + this.getName().toString() + "]");

      return result.toString();
   }
}

User
Code:
import java.util.HashSet;
import java.util.Set;
import javax.persistence.OneToMany;

import java.io.Serializable;

import javax.persistence.Entity;

import javax.persistence.GeneratorType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;


@Entity
@Table(name = "Sc000_User")
@Inheritance(strategy = InheritanceType.JOINED)
public class User
   implements Serializable
{
   @Id(generate = GeneratorType.AUTO)
   private long id;

   @OneToMany(mappedBy = "user")
   private Set<Group> groups;

   public User()
   {
  }

   @Id(generate = GeneratorType.AUTO)
   public long getId()
   {
      return this.id;
   }

   protected void setId(long id)
   {
      this.id = id;
   }

   @OneToMany(mappedBy = "user")
   public Set<Group> getGroups()
   {
      if (this.groups == null)
      {
         this.groups = new HashSet<Group>();
      }
      return this.groups;
   }

   public void setGroups(Set<Group> groups)
   {
      this.groups = groups;
   }

   public boolean equalsIgnorePrimaryKey(User other)
   {

      return true;
   }

   public boolean equals(User other)
   {
      if (other == null)
      {
         return false;
      }

      if (!(this.getId() == other.getId()))
      {
         return false;
      }

      return this.equalsIgnorePrimaryKey(other);
   }

   @Override
   public String toString()
   {
      StringBuffer result = new StringBuffer();

      result.append("id: [" + this.getId() + "]");

      return result.toString();
   }
}

Member
Code:
import java.util.Set;
import javax.persistence.ManyToMany;
import javax.persistence.PrimaryKeyJoinColumn;

import java.io.Serializable;

import javax.persistence.Entity;

import javax.persistence.Table;


@Entity
@Table(name = "Member")

@PrimaryKeyJoinColumn(name = "idSuperUser")
public class Member extends User
   implements Serializable
{
   private String name;
   @ManyToMany(mappedBy = "members")
   private Set<Group> groups;

   public Member()
   {
  }

   @ManyToMany(mappedBy = "members")
   public Set<Group> getGroups()
   {
      return this.groups;
   }

   public void setGroups(Set<Group> groups)
   {
      this.groups = groups;
   }

   public String getName()
   {
      return this.name;
   }

   public void setName(String name)
   {
      this.name = name;
   }

   public boolean equalsIgnorePrimaryKey(Member other)
   {
      if (!(this.getName().equals(other.getName())))
      {
         return false;
      }

      return true;
   }

   public boolean equals(Member other)
   {
      if (other == null)
      {
         return false;
      }

      if (!(super.getId() == other.getId()))
      {
         return false;
      }

      return this.equalsIgnorePrimaryKey(other);
   }

   @Override
   public String toString()
   {
      StringBuffer result = new StringBuffer();

      result.append("id: [" + super.getId() + "]").append(
            "\nname: [" + this.getName().toString() + "]");

      return result.toString();
   }
}

JUnit-Test reproducing the exception
Code:
import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import junit.textui.TestRunner;

import org.apache.log4j.Logger;

import de.ruu.util.ClassUtil;
import de.ruu.util.RuntimeUtil;
import de.ruu.util.j2ee.ejb.EntityManagerUtil;

public class JUTLifecycleMember extends TestCase
{
   private static final Class  CLASS = RuntimeUtil.getThisClass();
   private static final Logger LOGGER = ClassUtil.getClassLogger();

   private EntityManager     entityManager = null;
   private EntityTransaction entityTransaction = null;

   /**
    * stores the number of <code>Member</code> and related objects
    * that are to be created during this test
    */
   private static final int OBJECT_COUNT = 5;

   /**
    * stores the Member objects that were created during this test
    */
   private static final List<Member> CREATED = new ArrayList<Member>(
         OBJECT_COUNT);

   public JUTLifecycleMember()
   {
      super(CLASS.getName());
   }

   public JUTLifecycleMember(String name)
   {
      super(name);
   }

   @Override
   protected void setUp() throws Exception
   {
      this.entityManager = EntityManagerUtil.getCurrentEntityManager();
      this.entityTransaction = this.entityManager.getTransaction();

      this.entityTransaction.begin();
   }

   @Override
   protected void tearDown() throws Exception
   {
      this.entityTransaction.commit();
   }

   public static void main(String[] args)
   {
      TestRunner.run(JUTLifecycleMember.suite());
   }

   public static Test suite()
   {
      TestSuite suite = new TestSuite(CLASS.getName());

      suite.addTest(new JUTLifecycleMember("testCreate"));
      suite.addTest(new JUTLifecycleMember("testRead"));
      suite.addTest(new JUTLifecycleMember("testUpdate"));
      suite.addTest(new JUTLifecycleMember("testRead"));
      suite.addTest(new JUTLifecycleMember("testDelete"));
      suite.addTest(new JUTLifecycleMember("testReadDeleted"));

      return suite;
   }

   public void testCreate() throws Exception
   {
      Member object = null;

      for (int i = 0; i < OBJECT_COUNT; i++)
      {
         object = new Member();

         object.setName("name." + i);

         this.entityManager.persist(object);

         CREATED.add(object);
      }
   }

   public void testRead() throws Exception
   {
      for (Member object : CREATED)
      {
         object = this.entityManager.find(Member.class, object.getId());

         LOGGER.info(
               "success reading [" + Member.class.getName() + "] object:\n"
               + object.toString());

         if (!(this.isInList(object, CREATED)))
         {
            throw new Exception(
                  "failure, read [" + Member.class.getName()
                  + "] object that is not contained in the list of created objects");
         }
      }
   }

   public void testUpdate() throws Exception
   {
      for (Member object : CREATED)
      {
         object.setName(object.getName() + ".updated");

         object = this.entityManager.merge(object);

         LOGGER.info(
               "success updating [" + Member.class.getName()
               + "] object:\n" + object.toString());
      }
   }

   public void testDelete() throws Exception
   {
      for (Member object : CREATED)
      {
         this.entityManager.remove(object);

         LOGGER.info(
               "success deleting [" + Member.class.getName()
               + "] object:\n" + object.toString());
      }
   }

   public void testReadDeleted() throws Exception
   {
      for (Member object : CREATED)
      {
         object = this.entityManager.find(Member.class, object.getId());

         if (object != null)
         {
            throw new Exception(
                  "failure, read [" + Member.class.getName()
                  + "] object that should be deleted already:\n"
                  + object.toString());
         }
      }
   }

   private boolean isInList(
         Member object, List<Member> objectList)
   {
      for (Member listElement : objectList)
      {
         if (object.equals(listElement))
         {
            return true;
         }
      }

      return false;
   }
}

DDL
Code:
CREATE TABLE gsd.Group
(
   /* ordinary columns */
   name varchar(50) default NULL,

   /* primary key columns */
   id bigint(20) default NULL NOT NULL auto_increment,
   idRelatedUserUser bigint(20),
   PRIMARY KEY
   (
      id
   ),
   KEY keyRelatedUserUser
   (
      idRelatedUserUser
   )
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE gsd.Member
(
   /* ordinary columns */
   name varchar(50) default NULL,

   /* primary key columns */
   id bigint(20) NOT NULL auto_increment,
   idSuperUser bigint(20) default NULL,
   PRIMARY KEY
   (
      id
   ),
   KEY keySuperUser
   (
      idSuperUser
   )
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE gsd.User
(
   /* ordinary columns */

/* primary key columns */
   id bigint(20) default NULL NOT NULL auto_increment,
   PRIMARY KEY
   (
      id
   )
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE gsd.Group___Member
(
   idGroup bigint(20) NOT NULL,
   idMember bigint(20) NOT NULL,
   KEY keyManySc000
   (
      idGroup
   ),
   KEY keyManyMember
   (
      idMember
   )
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE gsd.Group
   ADD CONSTRAINT fkr_Group2User_User FOREIGN KEY
(
   idRelatedUserUser
) REFERENCES User
  (
     id
  );


ALTER TABLE gsd.Member
   ADD CONSTRAINT fks_User FOREIGN KEY
(
   idSuperUser
) REFERENCES User
  (
     id
  );

ALTER TABLE gsd.Group___Member ADD CONSTRAINT fkManyOwner_Group___Member FOREIGN KEY
(
   idGroup
) REFERENCES Group
  (
     id
  );
ALTER TABLE gsd.Group___Member ADD CONSTRAINT fkManyOwned_Group___Member FOREIGN KEY
(
   idMember
) REFERENCES Member
  (
     id
  );


Hibernate version: 3.1 rc2

Mapping documents: none, using annotations

Code between sessionFactory.openSession() and session.close(): see below

Full stack trace of any exception that occurs:
org.hibernate.HibernateException: Found shared references to a collection: Member.groups
at org.hibernate.engine.Collections.processReachableCollection(Collections.java:146)
at org.hibernate.event.def.FlushVisitor.processCollection(FlushVisitor.java:37)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:101)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:61)
at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:55)
at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:115)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:195)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:76)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:905)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:345)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:36)
at JUTLifecycleMember.tearDown(JUTLifecycleMember.java:87)
at junit.framework.TestCase.runBare(TestCase.java:130)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)




Name and version of the database you are using: MySql 4.1.9

The generated SQL (show_sql=true):

Debug level Hibernate log excerpt:

Code:


Top
 Profile  
 
 Post subject:
PostPosted: Sun Nov 27, 2005 10:38 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
same error as the user reporting the bug.
User.getGroups()
Member.getGroups()
User <= Member
=> same property cannot be mapped twice.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 28, 2005 5:11 pm 
Newbie

Joined: Wed Jan 07, 2004 12:02 pm
Posts: 15
Location: Herne, Germany
Thanks Emmanuel, I immediately understood what I did wrong when reading your reply. Maybe there is a way to let hibernate give a more obvious hint?


Top
 Profile  
 
 Post subject:
PostPosted: Sun Apr 16, 2006 8:15 pm 
Newbie

Joined: Sun Apr 16, 2006 7:51 pm
Posts: 1
Location: Germany, Oldenburg
Hallo.

I think I've got about the same Problem. There are two classes (Information, FlowOfGoods) which have to exact same references (source, target) to another object (RoleType). They both implement the interface Flow, which has the references, too. If two objects of FlowOfGoods or two objects of Information reference the same RoleType, I get an "Found shared references to a collection" exception.

Code of the interface:

public interface Flow {
public RoleType getSource();

public void setSource(RoleType source);

public RoleType getTarget();

public void setTarget(RoleType target);

public int getXSource();

public int getYSource();

public int getXTarget();

public int getYTarget();

public int getLefterX();

public void setLefterX(int lefterX);

public int getY();

public void setY(int y);

public int getRighterX();

public void setRighterX(int righterX);

public String toString();

public Set getCorrespondingSet();

public void setCorrespondingSet(Set correspondingSet);
}

I would like to use the interface furthermore. Is there a way?

In the postings above I can't see the solution.

I hope someone can help me.



Hibernate version: 3.0.5

Mapping documents:
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping
>
<class
name="de.uni_oldenburg.pglonesuch.model.FlowOfGoods"
table="FlowOfGoods"
>

<id
name="id"
column="id"
type="java.lang.Integer"
>
<generator class="native">
<!--
To add non XDoclet generator parameters, create a file named
hibernate-generator-params-FlowOfGoods.xml
containing the additional parameters and place it in your merge dir.
-->
</generator>
</id>

<many-to-one
name="carrier"
class="de.uni_oldenburg.pglonesuch.model.Carrier"
cascade="all"
outer-join="auto"
update="true"
insert="true"
column="CARRIER_ID"
/>

<property
name="deliveryTime"
type="integer"
update="true"
insert="true"
column="DELIVERYTIME"
/>

<many-to-one
name="goods"
class="de.uni_oldenburg.pglonesuch.model.Goods"
cascade="save-update"
outer-join="auto"
update="true"
insert="true"
column="GOODS_ID"
/>

<many-to-one
name="shipper"
class="de.uni_oldenburg.pglonesuch.model.RoleType"
cascade="save-update"
outer-join="auto"
update="true"
insert="true"
column="SHIPPER_ID"
/>

<many-to-one
name="source"
class="de.uni_oldenburg.pglonesuch.model.RoleType"
cascade="save-update"
outer-join="auto"
update="true"
insert="true"
column="SOURCE_ID"
/>

<many-to-one
name="target"
class="de.uni_oldenburg.pglonesuch.model.RoleType"
cascade="save-update"
outer-join="auto"
update="true"
insert="true"
column="TARGET_ID"
/>

<property
name="lefterX"
type="integer"
update="true"
insert="true"
column="LEFTERX"
/>

<property
name="righterX"
type="integer"
update="true"
insert="true"
column="RIGHTERX"
/>

<property
name="y"
type="integer"
update="true"
insert="true"
column="Y"
/>

<set
name="correspondingSet"
table="FlowOfGoods_Item"
lazy="false"
cascade="all"
sort="unsorted"
>

<key
column="ITEM_ID"
>
</key>

<many-to-many
class="de.uni_oldenburg.pglonesuch.model.Item"
outer-join="auto"
/>

</set>

<property
name="flowType"
type="integer"
update="true"
insert="true"
column="FLOW_TYPE"
/>

<!--
To add non XDoclet property mappings, create a file named
hibernate-properties-FlowOfGoods.xml
containing the additional properties and place it in your merge dir.
-->

</class>

</hibernate-mapping>

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping
>
<class
name="de.uni_oldenburg.pglonesuch.model.Information"
table="Information"
>

<id
name="id"
column="id"
type="java.lang.Integer"
>
<generator class="native">
<!--
To add non XDoclet generator parameters, create a file named
hibernate-generator-params-Information.xml
containing the additional parameters and place it in your merge dir.
-->
</generator>
</id>

<many-to-one
name="carrier"
class="de.uni_oldenburg.pglonesuch.model.Carrier"
cascade="all"
outer-join="auto"
update="true"
insert="true"
column="CARRIER_ID"
/>

<many-to-one
name="goods"
class="de.uni_oldenburg.pglonesuch.model.Goods"
cascade="all"
outer-join="auto"
update="true"
insert="true"
column="GOODS_ID"
/>

<property
name="name"
type="string"
update="true"
insert="true"
column="NAME"
/>

<property
name="type"
type="string"
update="true"
insert="true"
column="TYPE"
/>

<many-to-one
name="source"
class="de.uni_oldenburg.pglonesuch.model.RoleType"
cascade="all"
outer-join="auto"
update="true"
insert="true"
column="SOURCE_ID"
/>

<many-to-one
name="target"
class="de.uni_oldenburg.pglonesuch.model.RoleType"
cascade="all"
outer-join="auto"
update="true"
insert="true"
column="TARGET_ID"
/>

<property
name="lefterX"
type="integer"
update="true"
insert="true"
column="LEFTERX"
/>

<property
name="y"
type="integer"
update="true"
insert="true"
column="Y"
/>

<property
name="righterX"
type="integer"
update="true"
insert="true"
column="RIGHTERX"
/>

<set
name="correspondingSet"
table="Information_Item"
lazy="false"
cascade="all"
sort="unsorted"
>

<key
column="ITEM_ID"
>
</key>

<many-to-many
class="de.uni_oldenburg.pglonesuch.model.Item"
outer-join="auto"
/>

</set>

<property
name="flowType"
type="integer"
update="true"
insert="true"
column="FLOW_TYPE"
/>

<!--
To add non XDoclet property mappings, create a file named
hibernate-properties-Information.xml
containing the additional properties and place it in your merge dir.
-->

</class>

</hibernate-mapping>



Code between sessionFactory.openSession() and session.close(): see below

Found shared references to a collection
([/lonesuch].[SaveObject] 260 ) Servlet.service() for servlet SaveObject threw exception
java.lang.RuntimeException: Found shared references to a collection
at de.uni_oldenburg.pglonesuch.persistence.hibernate.HibernateSession.save(HibernateSession.java:95)
at de.uni_oldenburg.pglonesuch.administration.Model.saveConceptualModel(Model.java:553)
at de.uni_oldenburg.pglonesuch.persistence.comm.SaveObject.doPost(SaveObject.java:72)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:744)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Thread.java:595)


Name and version of the database you are using: MySql 4.1.14-r1

The generated SQL (show_sql=true):

Debug level Hibernate log excerpt:


Top
 Profile  
 
 Post subject: Re: "found shared references to a collection" with ejb
PostPosted: Wed Dec 02, 2009 10:37 am 
Newbie

Joined: Mon Nov 16, 2009 7:23 am
Posts: 7
I know this isn't directly relevant to the OP's issue, but as this topic comes up as the first result in Google when searching for "found shared references to collection", I thought I'd add another possibly common cause of this error.

Anything that causes a collection to be referenced by different objects can cause this error. The error is subtle and will only appear when those objects have been modified and need to be flushed.

In ruuit's case, as Emmanuel very tersely pointed out (too tersely for me to understand until I already knew what the problem was), the user and the member use the same key to the same collection type, and therefore they get identical collections out of the Hibernate cache (references to exactly the same PersistentSet). Hibernate doesn't detect that this is bad until you try to flush both objects at the same time, and both collections are initialized, when it throws the "found shared references to collection" error.

In my case, I caused the same problem a different way, by accidentally using a one-to-many association instead of a many-to-many, with a property-ref linking to a non-unique column. When I had two objects loaded that had the same value in the non-unique column, they got the same set, and when I tried to flush them both, I got this error.

I'm working on patching Hibernate to detect this error statically at configuration time instead of when the user happens to trigger it, which leaves latent, dangerous and difficult to diagnose bugs in the application.

If you get this error, check that the property it warns you about has a property reference that is unique across all loaded objects, so that the same value is not used to load the same collection in any other object.


Top
 Profile  
 
 Post subject: Re: "found shared references to a collection" with ejb
PostPosted: Fri Jun 18, 2010 3:12 pm 
Newbie

Joined: Fri Jun 18, 2010 3:08 pm
Posts: 1
gcc1,

Thank you for taking time to write your post. You helped me understand and quickly identify my issue, which was as you described.


Top
 Profile  
 
 Post subject: Re: "found shared references to a collection" with ejb
PostPosted: Fri Jul 23, 2010 10:03 am 
Newbie

Joined: Fri Jul 23, 2010 9:51 am
Posts: 1
I have the same exception but with only 1 mapping (sorry fro my very bad UK)

class Candidature
Code:
@Entity
@Table(name = "T_Candidature")
public class Candidature extends PersistentEntity<Candidature> {

    private static final long serialVersionUID = 1L;

 
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "Candidature_ID", nullable = false, unique = true)
    private Long id;

    @JoinColumn(name = "Pers_ID", referencedColumnName = "Pers_ID")
    @ManyToOne(optional = false)
    private Person person;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "candidature")
    private Set<VacancyChosen> vacanciesChosen = new TreeSet<VacancyChosen>();

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "candidature")
    private Set<TestLanguage> testLanguages = new TreeSet<TestLanguage>();


class TestLanguage
Code:
@Entity
@Table(name = "T_CandTestLanguage")
public class TestLanguage extends PersistentEntity<TestLanguage> {

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "web_sid", nullable = false)
     @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Enumerated(EnumType.STRING)
    @Column(name = "TestLanguage")
    private LanguageUpperCase lang;

    @ManyToOne(optional = false)
    @JoinColumn(name = "Candidature_ID", referencedColumnName = "Candidature_ID")
    private Candidature candidature;

    @ManyToOne(optional = false)
    @JoinColumn(name = "TestTypeLinkLanguage_ID", referencedColumnName = "TestTypeLinkLanguage_ID")
    private TestLanguageType testLanguageType;


and the class TestLanguageType
Code:
@Entity
@Table(name = "TC_TestTypeLinkLanguage")
public class TestLanguageType extends PersistentEntity<TestLanguageType> {

    private static final long serialVersionUID = 6327761301192925957L;

    @Id
    @Column(name = "TestTypeLinkLanguage_ID", nullable = false)
     @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name = "TestTypeLinkLanguage_F", nullable = false, length = 20)
    private String typeFr;

    @Column(name = "TestTypeLinkLanguage_N", nullable = false, length = 20)
    private String typeNl;

    @Transient
    private Map<String,String> types;


While updating a Candidature (adding an element to another collection then the TestLanguage) ...
Code:
2010-07-23 14:13:30,040 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[...].[dispatcher]] Servlet.service() for servlet dispatcher threw exception org.hibernate.HibernateException: Found shared references to a collection (hideFCQN).inscription.Candidature.testLanguages
at org.hibernate.engine.Collections.processReachableCollection(Collections.java:163)
   at org.hibernate.event.def.FlushVisitor.processCollection(FlushVisitor.java:37)
   at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:101)
   at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:61)
   at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:55)
   at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:138)
   at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:196)
   at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:76)
   at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
   at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
   at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
   at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
   at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:54)
   at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:456)
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:709)
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:678)
   at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:321)
   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:116)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
   at $Proxy128.addVacancyChosen(Unknown Source)
   at (hide).facade.SolicitationFacadeBean.addVacancyChosen(SolicitationFacadeBean.java:66)



I dont understand from where came this exception !

A big thanks for informations...

_________________
chatmar - java designer


Top
 Profile  
 
 Post subject: Re: "found shared references to a collection" with ejb
PostPosted: Wed Sep 29, 2010 4:00 pm 
Newbie

Joined: Wed Sep 29, 2010 3:57 pm
Posts: 1
Does anyone has a solution for it? Is disablinge the hibernate cache a working method to get rid off "Found shared references to a collection"?


Top
 Profile  
 
 Post subject: Re: "found shared references to a collection" with Hibernate
PostPosted: Tue Dec 14, 2010 4:27 am 
Newbie

Joined: Tue Dec 14, 2010 4:21 am
Posts: 3
I have getting "Found shared references to a collection" Same error is their any problem if i have written " hibernate.cache usage="read-only" include="all"" for that particular bean.
And this error got first time ever. So What will be problem .And What is solution to solve this?


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
cron
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.