-->
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.  [ 1 post ] 
Author Message
 Post subject: Parent/Child Example (Ref. Docs) + NonUniqueObjectException
PostPosted: Fri Jan 19, 2007 10:19 am 
Newbie

Joined: Fri Jan 19, 2007 7:11 am
Posts: 1
Hello everybody,

I recently started working with Hibernate and to get some first impressions I was playing around with the "Parent/Child" example in the reference documentation.

My problem is that I always get an NonUniqueObjectException when trying to add the same Child twice to the same Parent.
I'm using assigend identifiers, a version property and a addChild() method in the Parent class (as described in the ref docs).
I specified thread-bound transaction management in the hibernate.cfg.xml configuration file.

I apologize that this might be a really stupid question, but I just cannot figure out what I'm doing wrong. I've spent days reading the docs, searching the forum and the internet and everything I tried didn't work. I really hope somebody can give me some clues as to what I'm doing wrong.

Thanks a lot,
Martin

P.S.: I tried to isolate the error and it seems it occurs because of the line "this.getChildren().add(child);" in the method addChid() of the Parent class.

Hibernate version:
3.2.1 GA

Mapping documents:
HIBERNATE.CFG.XML
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
   "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

    <session-factory>

        <property name="connection.driver_class">org.postgresql.Driver</property>
        <property name="connection.url">jdbc:postgresql://localhost/PARENTCHILD</property>
        <property name="connection.username">postgres</property>
        <property name="connection.password">postgres</property>
       
        <property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
       
        <property name="current_session_context_class">thread</property>     
        <property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
       
         <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
        <property name="cache.use_query_cache">false</property>
        <property name="cache.use_minimal_puts">false</property>
       
         <property name="show_sql">true</property>
        <property name="format_sql">true</property>
        <property name="use_sql_comments">true</property>
       
         <mapping resource="Parent.hbm.xml"/>
        <mapping resource="Child.hbm.xml"/>

    </session-factory>

</hibernate-configuration>


JAVA CODE: PARENT

Code:
import java.util.*;

public class Parent {
   private String id;
   private Integer version;
   private String name;
   private Set<Child> children = new HashSet<Child>();

   public Parent() {}

   public String getId() { return id; }

   public void setId(String id) { this.id = id; }

   public Integer getVersion() { return version; }

   public void setVersion(Integer version) { this.version = version; }
   
   public String getName() { return name; }

   public void setName(String name) { this.name = name; }
   
   public Set<Child> getChildren() { return children; }

   public void setChildren(Set<Child> set) { this.children = set; }
      
   public void addChild(Child child) {
      child.setParent(this);
      this.getChildren().add(child);      
   }
}


MAPPING: PARENT

Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
   <class name = "Parent" table = "PARENT">
      <id name = "id" column = "P_ID">
         <generator class = "assigned"></generator>
      </id>      
      <version name="version" column="P_VERSION"/>
      <property name = "name" column = "P_NAME" type = "string"></property>
      <set name = "children" inverse = "true" cascade="all-delete-orphan">
         <key column = "P_ID"/>
         <one-to-many class = "Child"/>
      </set>      
   </class>
</hibernate-mapping>


JAVA CODE: CHILD

Code:
import java.util.*;

public class Child {
   private String id;
   private Integer version;
   private Parent parent;
   private String name;
   
   public Child() {}
   
   public String getId() { return id; }
   public void setId(String id) { this.id = id; }
   public Integer getVersion() { return version; }
   public void setVersion(Integer version) { this.version = version; }
   public Parent getParent() { return parent; }
   public void setParent(Parent parent) { this.parent = parent; }
   public String getName() { return name; }
   public void setName(String name) { this.name = name; }
}


MAPPING: CHILD

Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
   <class name = "Child" table = "CHILD">
      <id name = "id" column = "C_ID">
         <generator class = "assigned"></generator>
      </id>
      <version name="version" column="C_VERSION"/>
      <property name = "name" column = "C_NAME" type = "string"/>
      <many-to-one name = "parent" column = "P_ID" not-null = "true"/>
      </class>
</hibernate-mapping>


Code between sessionFactory.openSession() and session.close():
JAVA: TEST CLASS

Code:
import org.hibernate.*;

public class ParentChildTest {

   public void insertParent(Parent p) {
      Session s = HibernateUtil.getSessionFactory().getCurrentSession();
      s.beginTransaction();
      s.save(p);
      s.getTransaction().commit();
   }
   
   public void insertChild(Child c) {
      Session s = HibernateUtil.getSessionFactory().getCurrentSession();
      s.beginTransaction();
      Parent p = (Parent)s.get(Parent.class, c.getParent().getId());
      p.addChild(c);
      s.getTransaction().commit();
   }
   
   public static void main(String[] args) {
      
      ParentChildTest t = new ParentChildTest();
      
      Parent p = new Parent();
      p.setId("P_01");
      p.setName("Arnold Schwarzenegger");
      
      t.insertParent(p);
      
      Child c = new Child();
      c.setId("C_01");
      c.setParent(p);
      c.setName("Sylvester Stallone");
      
      t.insertChild(c);
         
      t.insertChild(c);      
   }
}


Full stack trace of any exception that occurs:
Code:
Exception in thread "main" org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [Child#C_01]
   at org.hibernate.engine.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:556)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:259)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:217)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
   at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:507)
   at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:499)
   at org.hibernate.engine.CascadingAction$1.cascade(CascadingAction.java:218)
   at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:268)
   at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:216)
   at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
   at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:296)
   at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:242)
   at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:219)
   at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
   at org.hibernate.engine.Cascade.cascade(Cascade.java:130)
   at org.hibernate.event.def.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:131)
   at org.hibernate.event.def.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:122)
   at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:65)
   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 ParentChildTest.insertChild(ParentChildTest.java:23)
   at ParentChildTest.main(ParentChildTest.java:43)


Name and version of the database you are using:
PostgreSQL 8.2.1

The generated SQL (show_sql=true):

Debug level Hibernate log excerpt:


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

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:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.