-->
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.  [ 3 posts ] 
Author Message
 Post subject: Yes, it's another NonUniqueObjectException...
PostPosted: Tue Oct 09, 2007 5:39 am 
Newbie

Joined: Tue Oct 09, 2007 4:48 am
Posts: 11
Hello,

I would sincerely appreciate it if anyone could have a quick look at this and let me know where I'm going wrong.

I can supply complete mapping files, SQL traces etc, but to try and keep things as compact as possible I am going to just put up my test case which at least may give you an idea of where the fault lies. I've included mapping file fragments in the body of the test case.

I am using Hibernate 3.2.2 on MySQL 5.0.27.

It's a reasonably simple model -
    A 'Project' has a list of 'ContactList' objects
    A 'ContactList' has a list of 'Person' objects
    A Person has a single Organisation object
There are things that complicate it a bit:
    A 'ContactList' has a back reference to the 'Project'
    An 'Organisation' has a back reference to a set of 'Person' objects


Here is my test case:

Code:
   public void testAddPersonToExistingStaticList(){
      //first, create a bunch of people...
      Person p1 = new Person();
      Person p2 = new Person();
      Person p3 = new Person();
      p1.setFirstName("Test");
      p1.setLastName("Person 1");
      p2.setFirstName("Test");
      p2.setLastName("Person 2");
      p3.setFirstName("Test");
      p3.setLastName("Person 3");      
      
      //All the people are in the same organisation...
      Organisation o1 = new Organisation();      
      o1.setName("Organisation 1");
      p1.setOrganisation(o1);
      p2.setOrganisation(o1);
      p3.setOrganisation(o1);
      /**
       * 'Person' HBM Fragment:      
       * <many-to-one name="organisation" class="Organisation"
       * not-null="false" lazy="false" cascade="save-update">
       *    <column name="orgID" />
       * </many-to-one>   
       */
      
      //save all people (this works fine)
      applicationService.savePerson(p1);
      applicationService.savePerson(p2);
      applicationService.savePerson(p3);
      
      String testId = String.valueOf(new Date().getTime()); //just a unique id for this test run...

      //create a new project (Project is a container for 'ContactLists')
      Project project = new Project();
      project.setName("Project " + testId);
      /**
       * 'Project' HBM Fragment:      
       * <list name="contactLists" cascade="save-update" lazy="false">
       *    <key column="projectId" not-null="true"/>
       *    <list-index column="contactListIdx"/>
       *    <one-to-many class="ContactList"/>
       * </list>
       */
      
      //add a list to the project (A contactlist is a collection of people)
      ContactListStatic cls = new ContactListStatic();
      cls.setListName("Contact List " + testId);
      cls.setMyProject(project);
      project.getContactLists().add(cls);
      /**
       *  Back reference HBM Fragment:
       *    <many-to-one name="myProject" lazy="false"
         column="projectId"
         not-null="true"
         insert="false"
         update="false"/>
       */      
      
      
      //add a few people to the list
      cls.getPeople().add(p1);
      cls.getPeople().add(p2);
      /**
       * 'ContactListStatic' HBM Fragment:
       * <subclass name="ContactListStatic" discriminator-value="STATIC">
       *    <list name="people" lazy="true" cascade="save-update">
       *       <key column="contactListId" not-null="true"/>
       *       <index column="personIdx" />
       *       <many-to-many class="Person" />
       *    </list>
       * </subclass>
       */
      
      //save the new project (this works fine)
      applicationService.saveProject(project);

      
      //From an application point of view, this text represents time passing...


      //now, we want to add the final person to the (already existing) list...
      List cl = applicationService.findContactLists("Contact List " + testId);
      ContactListStatic clsRetrieved = (ContactListStatic)cl.get(0);
      int numberPeople = applicationService.findNumberInStaticList(clsRetrieved);
      assertEquals(numberPeople, 2);
      clsRetrieved.getPeople().add(p3);
      

      applicationService.saveProject(clsRetrieved.getMyProject());
      //fails, because the organisation o1 is already present in the session...
      /*
       * org.springframework.orm.hibernate3.HibernateSystemException:
       * a different object with the same identifier value was already associated with the session:
       * [com.rm.application.model.Organisation#34];
       *
       * nested exception is org.hibernate.NonUniqueObjectException:
       * a different object with the same identifier value was already associated with the session:
       * [com.rm.application.model.Organisation#34]
       *
       * Caused by: org.hibernate.NonUniqueObjectException:
       * a different object with the same identifier value was already associated with the session:
       * [com.rm.application.model.Organisation#34]
       */
      //applicationService.mergeProject(clsRetrieved.getMyProject());
      //works, but the newly added person (p3) is missing...
   }


There's clearly something silly I'm doing, but I just can't see it.

Will gladly post up any config stuff that will help in sorting this out.

Many thanks.

James.

PS. Full stack trace in case it helps is:
Code:

org.springframework.orm.hibernate3.HibernateSystemException: a different object with the same identifier value was already associated with the session: [com.rm.application.model.Organisation#69]; nested exception is org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.rm.application.model.Organisation#69]
Caused by: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.rm.application.model.Organisation#69]
   at org.hibernate.engine.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:577)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:284)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:223)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:89)
   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.cascade(Cascade.java:130)
   at org.hibernate.engine.Cascade.cascade(Cascade.java:97)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.cascadeOnUpdate(DefaultSaveOrUpdateEventListener.java:357)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:329)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:223)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:89)
   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.engine.Cascade.cascade(Cascade.java:97)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.cascadeOnUpdate(DefaultSaveOrUpdateEventListener.java:357)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:329)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:223)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:89)
   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.engine.Cascade.cascade(Cascade.java:97)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.cascadeOnUpdate(DefaultSaveOrUpdateEventListener.java:357)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:329)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:223)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:89)
   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.impl.SessionImpl.saveOrUpdate(SessionImpl.java:495)
   at org.springframework.orm.hibernate3.HibernateTemplate$16.doInHibernate(HibernateTemplate.java:684)
   at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:367)
   at org.springframework.orm.hibernate3.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:681)
   at com.rm.application.service.io.ApplicationDAOHibernate.saveProject(ApplicationDAOHibernate.java:231)
   at com.rm.application.service.ApplicationServiceImpl.saveProject(ApplicationServiceImpl.java:94)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
   at java.lang.reflect.Method.invoke(Unknown Source)
   at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:281)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:187)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:154)
   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:176)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:210)
   at $Proxy1.saveProject(Unknown Source)
   at com.rm.application.test.TestApplicationService.testAddPersonToExistingStaticList(TestApplicationService.java:302)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
   at java.lang.reflect.Method.invoke(Unknown Source)
   at junit.framework.TestCase.runTest(TestCase.java:154)
   at junit.framework.TestCase.runBare(TestCase.java:127)
   at org.springframework.test.ConditionalTestCase.runBare(ConditionalTestCase.java:69)
   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 org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:128)
   at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)



Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 09, 2007 10:28 am 
Regular
Regular

Joined: Mon Jan 22, 2007 10:32 am
Posts: 101
Though I am not sure but I feel that problem is related to the way Organization object is mapped in Person hbm.

Code:
/**
       * 'Person' HBM Fragment:     
       * <many-to-one name="organisation" class="Organisation"
       * not-null="false" lazy="false" cascade="save-update">
       *    <column name="orgID" />
       * </many-to-one>   
       */


Why do you have a cascade="save-update" here? I think that Organization --> Person is a one-to-many relationship and you should first save the organization object and then the related person objects.

Just a wild guess.


Top
 Profile  
 
 Post subject: Thanks!
PostPosted: Tue Oct 09, 2007 12:17 pm 
Newbie

Joined: Tue Oct 09, 2007 4:48 am
Posts: 11
Many thanks for your reply.

Your suggestion (taking off the organisation cascade and manually persisting the organisation) worked.

Excellent stuff!

James.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 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:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.