-->
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.  [ 6 posts ] 
Author Message
 Post subject: TransientObjectException when persisting object graph
PostPosted: Mon Jul 26, 2004 7:48 pm 
Regular
Regular

Joined: Thu Jul 01, 2004 12:13 am
Posts: 68
Location: San Diego, CA
We have a fairly complex object representing our DB structure. When I try to persist, I get a TransientObjectException. I am only doing one save at the root table and have cascade="all" for all sets associated. However, I am trying to persist data to tables that are not directly related to the root object (i.e., children of children), but my thought is that if I have cascade="all on all my relations I should be able to persist ALL objects in the object graph at once. Is this an incorrect assumption?

You can see in the relation where I am indirectly connected to the Vehicle object, and it's this object it complains about. Here is a sample relation:

Code:
<hibernate-mapping package="com.mitchell.services.technical.claim.dao.vo">
   <class
      name="ClmClaim"
      table="CLM_CLAIM"
   >
      <id
         name="id"
         type="java.lang.Long"
         column="CLAIM_ID"
      >
         <generator class="sequence">
            <param name="sequence">CLAIM_ID_SEQ</param>
         </generator>         
      </id>
      <version name="tcn" column="TCN" type="long"/>
      

      <set cascade="all" inverse="true" name="clmPartySet">
         <key column="CLAIM_ID" />
         <one-to-many class="ClmParty" />
      </set>


   </class>
</hibernate-mapping>


<hibernate-mapping package="com.mitchell.services.technical.claim.dao.vo">
   <class
      name="ClmParty"
      table="CLM_PARTY"
   >
      <id
         name="id"
         type="java.lang.Long"
         column="PARTY_ID"
      >
         <generator class="sequence">
            <param name="sequence">PARTY_ID_SEQ</param>
         </generator>
      </id>

      <many-to-one
         name="claimVehicle"
         class="ClmClaimVehicle"
         not-null="true"
      >
         <column name="CLAIM_VEHICLE_ID"/>
      </many-to-one>

      <many-to-one
         name="claim"
         class="ClmClaim"
         not-null="true"
      >
         <column name="CLAIM_ID"/>
      </many-to-one>



   </class>
</hibernate-mapping>


<hibernate-mapping package="com.mitchell.services.technical.claim.dao.vo">
   <class
      name="ClmClaimVehicle"
      table="CLM_CLAIM_VEHICLE"
   >
      <id
         name="id"
         type="java.lang.Long"
         column="CLAIM_VEHICLE_ID"
      >
         <generator class="sequence">
            <param name="sequence">CLAIM_VEHICLE_ID_SEQ</param>
         </generator>
      </id>
      <version name="tcn" column="TCN" type="long"/>


      <set cascade="all" inverse="true" name="clmPartySet">
         <key column="CLAIM_VEHICLE_ID" />
         <one-to-many class="ClmParty" />
      </set>

      <set cascade="all" inverse="true" name="clmClaimExposureSet">
         <key column="CLM_VEH_CLAIM_VEHICLE_ID" />
         <one-to-many class="ClmClaimExposure" />
      </set>



   </class>
</hibernate-mapping>


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 27, 2004 12:51 pm 
Regular
Regular

Joined: Thu Jul 01, 2004 12:13 am
Posts: 68
Location: San Diego, CA
trolling...


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 27, 2004 1:54 pm 
Regular
Regular

Joined: Thu Jul 01, 2004 12:13 am
Posts: 68
Location: San Diego, CA
Here is the following error message I receive with the log4j logs. I am curious as to how others are handling complex relationships between tables, especially when circular indirect references between tables in the schema.

Thanks,
Lou

Code:
10:31:55,173 DEBUG SessionImpl:1371 - saveOrUpdate() persistent instance
10:31:55,173 DEBUG Cascades:506 - done processing cascades for: com.mitchell.services.technical.claim.dao.vo.ClmClaimActivityLog
10:31:55,188 DEBUG SessionImpl:2435 - Flushing entities and processing referenced collections
10:31:55,204 DEBUG SessionImpl:2880 - Collection found: [com.mitchell.services.technical.claim.dao.vo.ClmClaim.clmPartySet#90], was: [<unreferenced>]
10:31:55,204 DEBUG SessionImpl:2880 - Collection found: [com.mitchell.services.technical.claim.dao.vo.ClmClaim.exposureSet#90], was: [<unreferenced>]
10:31:55,220 DEBUG SessionImpl:2880 - Collection found: [com.mitchell.services.technical.claim.dao.vo.ClmClaim.clmDiarySet#90], was: [<unreferenced>]
10:31:55,220 DEBUG SessionImpl:2880 - Collection found: [com.mitchell.services.technical.claim.dao.vo.ClmClaim.clmAlertSet#90], was: [<unreferenced>]
10:31:55,220 DEBUG SessionImpl:2880 - Collection found: [com.mitchell.services.technical.claim.dao.vo.ClmClaim.activityLogSet#90], was: [<unreferenced>]
10:31:55,235 DEBUG SessionImpl:2880 - Collection found: [com.mitchell.services.technical.claim.dao.vo.ClmClaim.clmAttachmentSet#90], was: [<unreferenced>]
net.sf.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.mitchell.services.technical.claim.dao.vo.ClmClaimVehicle
   at net.sf.hibernate.impl.SessionImpl.throwTransientObjectException(SessionImpl.java:2764)
   at net.sf.hibernate.impl.SessionImpl.getEntityIdentifierIfNotUnsaved(SessionImpl.java:2756)
   at net.sf.hibernate.type.EntityType.getIdentifier(EntityType.java:66)
   at net.sf.hibernate.type.EntityType.isDirty(EntityType.java:139)
   at net.sf.hibernate.type.TypeFactory.findDirty(TypeFactory.java:225)
   at net.sf.hibernate.persister.AbstractEntityPersister.findDirty(AbstractEntityPersister.java:267)
   at net.sf.hibernate.impl.SessionImpl.flushEntity(SessionImpl.java:2504)
   at net.sf.hibernate.impl.SessionImpl.flushEntities(SessionImpl.java:2454)
   at net.sf.hibernate.impl.SessionImpl.flushEverything(SessionImpl.java:2256)
   at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2235)
   at com.mitchell.services.technical.claim.dao.ibatis.BaseIbatisHibernateDao.save(BaseIbatisHibernateDao.java:408)
   at com.mitchell.services.technical.claim.dao.ibatis.ClmClaimHibernateDao.save(ClmClaimHibernateDao.java:56)
   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 com.ibatis.dao.engine.impl.DaoProxy.invoke(DaoProxy.java:61)
   at $Proxy5.save(Unknown Source)
   at com.mitchell.services.technical.claim.dao.junit.ClaimDaoLocalTest.testSaveClaim(ClaimDaoLocalTest.java:61)
   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 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:421)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:305)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:186)
10:31:55,266 DEBUG SessionImpl:573 - closing session
10:31:55,266 DEBUG SessionImpl:3332 - disconnecting session


Top
 Profile  
 
 Post subject: Saving complex object graphs
PostPosted: Fri Jan 13, 2006 10:51 pm 
Newbie

Joined: Fri Jan 13, 2006 10:14 pm
Posts: 2
I've inherited a quite complex schema and struggle with this too. The hibernate cascade process is recursive, so it is tricky with deep relationships to follow.

Basically there are 3 steps to save() for each object
1) Cascade to save all the objects this object depends on for FK's (many-to-one associations)
2) Save the object
3) Cascade any collections the object declares with cascade="save-update"

Step's 1 and 3 are of course recursive. If you turn on logging of org.hibernate.engine.Cascades as debug you will be able to follow this recursion (it would be nice if these log events included the current cascade depth from the persister!).

I wonder why the other end of a many-to-one association is not cascaded to by default on save (if the FK is not-nullable this should be forced?).


Top
 Profile  
 
 Post subject: Re: TransientObjectException when persisting object graph
PostPosted: Sat Jan 14, 2006 2:11 am 
Senior
Senior

Joined: Tue Aug 23, 2005 8:52 am
Posts: 181
lsacco wrote:
We have a fairly complex object representing our DB structure. When I try to persist, I get a TransientObjectException. I am only doing one save at the root table and have cascade="all" for all sets associated. However, I am trying to persist data to tables that are not directly related to the root object (i.e., children of children), but my thought is that if I have cascade="all on all my relations I should be able to persist ALL objects in the object graph at once. Is this an incorrect assumption?


Im not sure if the one cascade that you set at the top will cascade down to unrelated collections. For e.g. In this case, you have set the cascade on the "clmPartySet" which will cascade to any relations in the ClmParty object but I think it stops there. If you want an unrelated collection in that ClmParty to further cascade down, you might need a cascade on the many-to-one mapping on "claimVehicle" property too.
I have not tried such a mapping but it looks like u might need a cascade on the claimVehicle mapping.


Top
 Profile  
 
 Post subject: Cascade through many-to-one.
PostPosted: Mon Jan 16, 2006 11:55 am 
Newbie

Joined: Fri Jan 13, 2006 10:14 pm
Posts: 2
Yes, rajasaur is correct, the docs state that cascades through associations are off by default, see Transitive Persistence section.

So this means cascade will stop for your case at ClmParty, and not cascade through the association:
Code:
<many-to-one name="claimVehicle"
                      class="ClmClaimVehicle"
                      not-null="true"
>


So Hibernate is complaining because the association ClmParty.claimVehicle does (did) not allow it to save the ClmClaimVehicle and it encountered a ClmClaimVehicle object in your graph that had not been previously saved.

Since neither end of the ClmParty may be null, you have only two options:

  1. Turn off all cascading and save, in order, ClmClaim, ClmClaimVehicle then lastly ClmParty.
  2. Turn on cascading for save on both of the many-to-one associations in ClmClaimVehicle


IMHO this could be better explained in the docs with some examples that included multiple related parent/child relations, but what do you want for free?

If the object graph is very large and interconnected it usually makes sense somewhere to break it up, dividing at many-to-many joining points (where either side of the many-to-many can be saved independently). I wish the folks that designed the schema I have inherited would have thought this through more carefully.

Hope this helps.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 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.