Tuesday, December 6, 2011

TransientObjectException - hibernate

org.hibernate.TransientObjectException: object references an unsaved transient instance – save the transient instance before flushing: com.swacorp.pcs.common.model.ServiceLevel
<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);
Hibernate defines and supports the following object states:

  * Transient :- an object is transient if it has just been instantiated using the new operator, and it is not associated with a Hibernate Session. It has no persistent representation in the database and no identifier value has been assigned.

  * Persistent :- a persistent instance has a representation in the database and an identifier value. It might just have been saved or loaded, however, it is by definition in the scope of a Session.

  * Detached :- a detached instance is an object that has been persistent, but its Session has been closed. The reference to the object is still valid, of course, and the detached instance might even be modified in this state. A detached instance can be reattached to a new Session at a later point in time, making it persistent again.

My changes:
HibernateTemplate template = getHibernateTemplate();
   Session session = template.getSessionFactory().getCurrentSession();
   itmAndPaxItmEvntOccrs.paxItm.setSvcLvl((ServiceLevel)session.get(itmAndPaxItmEvntOccrs.paxItm.getSvcLvl().getClass(), new Long(1)));
   template.saveOrUpdate(itmAndPaxItmEvntOccrs.paxItm);

14 comments:

  1. Thank you! This post helped me fix a bug I had been wrestling with.

    ReplyDelete
  2. Good to know. You are welcome Michael.

    ReplyDelete
  3. This does not work.

    package bert.entity;

    import javax.persistence.*;
    import java.util.Set;

    @Entity
    @Table(name = "EXCHANGE_INST")
    public class Exchange {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "Exchange_ID_GENERATOR")
    @SequenceGenerator(name = "Exchange_ID_GENERATOR",sequenceName = "Exchange_ID_SEQUENCER" , initialValue = 1 , allocationSize = 1)
    @Column(name = "Exchange_ID")
    private int Id;

    @Column(name = "Exchange_name")
    private String name;

    @OneToOne
    @JoinColumn(insertable = false,updatable = false)
    private Section section;

    public Exchange() {
    }

    public Exchange(String name) {
    this.name = name;
    }

    public int getId() {
    return Id;
    }

    public void setId(int id) {
    Id = id;
    }

    public String getName() {
    return name;
    }

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

    public Section getSection() {
    return section;
    }

    public void setSection(Section section) {
    this.section = section;
    }

    @Override
    public String toString() {
    return "Exchange{" +
    "Id=" + Id +
    ", name='" + name + '\'' +
    ", section=" + section +
    '}';
    }
    }


    package bert.entity;

    import javax.persistence.*;

    @Entity
    @Table(name = "Section_INST")
    public class Section {

    @javax.persistence.Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "Section_ID_GENERATOR")
    @SequenceGenerator(name = "Section_ID_GENERATOR",sequenceName = "Section_ID_SEQUENCER" , initialValue = 1 , allocationSize = 1)
    @Column(name = "Section_ID")
    private int Id;

    @Column(name = "Section_Name")
    private String name;

    @OneToOne()
    @JoinColumn(name = "Exch_ID",insertable = false,updatable = false)
    private Exchange exchange;

    public Section() {
    }

    public Section(String name, Exchange exchange) {
    this.name = name;
    this.exchange = exchange;
    }

    public int getId() {
    return Id;
    }

    public void setId(int id) {
    Id = id;
    }

    public String getName() {
    return name;
    }

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

    public Exchange getExchange() {
    return exchange;
    }

    public void setExchange(Exchange exchange) {
    this.exchange = exchange;
    }

    @Override
    public String toString() {
    return "Section{" +
    "Id=" + Id +
    ", name='" + name + '\'' +
    ", exchange=" + exchange +
    '}';
    }
    }



    package bert.entity;

    import com.manish.association.oneToOne.bi.joinColumn.User1;
    import com.manish.association.oneToOne.bi.joinColumn.Vehicle1;
    import org.hibernate.HibernateException;
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;

    public class DataSetup1 {


    public static void main(String[] args) {
    final Configuration configuration = new Configuration();
    try {
    configuration.configure("hibernate.cfg.xml");
    } catch (HibernateException e) {
    e.printStackTrace();
    }
    final SessionFactory sessionFactory = configuration.buildSessionFactory();
    final Session session = sessionFactory.openSession();
    session.beginTransaction();

    final Exchange exchange = new Exchange("MyExchange");
    final Section section = new Section("MySection" , exchange);
    exchange.setSection(section);
    session.save(exchange);

    session.getTransaction().commit();
    session.close();
    }
    }


    Try this.Still Exception.

    ReplyDelete

  4. Whoa! I’m enjoying the template/theme of this website. It’s simple, yet effective. A lot of times it’s very hard to get that “perfect balance” between superb usability and visual appeal. I must say you’ve done a very good job with this.

    AWS certification Training Online Bangalore
    AWS Certification Training Online Pune
    AWS certification Training Online Chennai
    AWS Online Certification and Training

    ReplyDelete
  5. This comment has been removed by the author.

    ReplyDelete
  6. Your post shows all your effort and great experience towards your work Your Information is Great if mastered very well. Great content thanks for sharing this informative blog which provided me technical information keep posting.
    aws training in chennai | aws training in annanagar | aws training in omr | aws training in porur | aws training in tambaram | aws training in velachery

    ReplyDelete
  7. "I simply wanted to thank you. I do not know what would have I done, as reading this information made things so easy to understand.
    keep sharing more information!!

    Android Training in Chennai

    Android Online Training in Chennai

    Android Training in Bangalore

    Android Training in Hyderabad

    Android Training in Coimbatore

    Android Training

    Android Online Training

    ReplyDelete
  8. Thanks for any other wonderful post. Where else may just anyone get that type of info in such a perfect means of writing? I’ve a presentation next week, and I am on the look for such information.


    oracle training in chennai

    oracle training in velachery

    oracle dba training in chennai

    oracle dba training in velachery

    ccna training in chennai

    ccna training in velachery

    seo training in chennai

    seo training in velachery

    ReplyDelete