org.hibernate.TransientObjectException Revisited

This is continuation of my earlier post on org.hibernate.TransientObjectException. Let me write the scenario again

<class name=”com.xxx.A” table=”A” schema=”TESTSCHEMA”>
<id name=”aId” type=”java.lang.Long”>
<column name=”A_ID” precision=”29″ scale=”0″ />
</id>

…………………..
some more mapping elements
…………………..
…………………..
<many-to-one name=”bId” class=”com.xxx.B” fetch=”select”>
<column name=”B_ID” precision=”29″ scale=”0″ />
</many-to-one>

…………………..

A is referring to B using a primary key column of bId of B.

In that post I have mentioned that if B is a transient object and you don’t want to persist the value of B to A then just tell the hibernate to ignore that value by saying
update=”false” insert=”false” in the many to one mapping.

But what if you want to persist the value of foreign key in A.

Then the approach is different. You have to make sure that instance B is persistent not transient.

That is if your code says something like

A a = new A();
B b = new B();
a.setB(b);
…..
…..

session.save(a);

you are in trouble. Because B is in transient state. You have to attach b to the session.
There may be other ways of attaching this transient object to session. The approach I am following is simple. I am reading the value of B from the database using Hibernate. That way, hibernate attaches B to session and it is then a persistent object.

That is I do something like

A a = new A();
B b = session.get(B.class, new Long(1));
a.setB(b);
…..
…..

session.save(a);

I won’t get any exception because this time there is no transient object to save. All the objects are persistent.

Powered by ScribeFire.

14 thoughts on “org.hibernate.TransientObjectException Revisited

  1. Dave Bates

    Sorry should have finished my previous post. the update=”false” insert=”false” works just fine, but why is it required when I have just loaded the value of the many to one column from the database? Should be the same sessions right? Right in the same method… And there are other very similar properties (i am initializing the same way) that don’t have the problem. That is what is strange.

    Reply
  2. Anand

    Hi paras,
    could you help me
    how to do this with JPA
    A a = new A();
    B b = session.get(B.class, new Long(1));
    a.setB(b);
    …..
    …..

    session.save(a);
    TIA
    kirti

    Reply
  3. Jeff

    Hello there,

    For new objects, as Niraj one, I found a solution, but maybe its not the best one.

    A a = new A();
    B b = new B();
    a.setB(b);

    session.save(b);
    session.save(a);

    session.commit();

    Well, the problem comes when I try to attach a Set to session; for each instance stored in the Set, I have to make a call to session.save(currentObject); these iteration is a really nasty way to resolve the problem, but works fine for me.

    Maybe something better?

    Reply
  4. Paras

    Thanks Jeff for contributing. I must admit that my post is a little obsolete. I will have to update it based on current hibernate version and my knowledge on that.

    Reply
  5. Jeff

    A bit more about this issue:

    Be sure your id generator option is not set to “assigned”. If your have something like that:

    Turn class to “increment”. If you dont, it throws this issue because the parent object has not an identifier assigned yet.

    See you.

    Reply
  6. Paras

    And if you want to keep generator as “assigned” then make sure you assign “unique” id to the object before persisting

    Reply
  7. Pingback: 2010 in review « Techspace

  8. Vikas

    Hi Niraj..

    Please use the below statements..if you are using annotations..and want to save both parent and child as new objects..
    then inside the Bean of parent class use

    @OneToOne(cascade = CascadeType.ALL)
    above the child member..

    it works. 🙂

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *