Understanding org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing:

August 12th, 2008 | by Priyatam |

Debugging Hibernate exceptions for users not so familiar with Hibernate can be frustrating. The following exception is a common source of error:-

Lets try to understand the error with a use case first. The most common scenario when this exception occurs is while trying to save a collection object (but calling save/persist on parent)

Consider the objects Foo has a OneToMany Bars

Foo.java

class Foo {
   List bars = new ArrayList();

  @OneToMany (mappedBy="foo")
   public List<Bar> getBars() {
	return bars;
   }

   addBar(Bar bar) {
       bars.add(bar)
       bar.setFoo(this);
    }
}

Bar.java

class Bar {

   Foo foo;

   @ManyToOne(fetch=FetchType.LAZY)
   @JoinColumn (nullable=false)
   public Fund getFoo() {
	return this.foo;
   }
}

The mapping seems fine and one would expect after adding Bars via addBar (lets say a snappy ui datatable where rows need to be adding dynamically). One could think of adding via addBar() many times and once user is complete and hits on “save”, we could call
entityManager.persist() or hibSession.save() and you are surprised why you got

org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing:

You curse Hibernate and you expect it to save all the children but it didn’t. The solution is, add a cascade to the parent. (unless you want to fire a save every time user adds a row, in which case you should save the bar first)

@OneToMany (mappedBy="foo" cascade=cascade=CascadeType.ALL)
public List<Bar> getBars() {
	return bars;
}

That’s it. You can now expect hibernate to cascade all persistent operations to it’s children without individually saving each

Post a Comment