Skip to content

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

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

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

2 Comments

  1. Sarah wrote:

    Hi,
    I have a case similar to the above, but even with the cascade set to ALL, i still have the same error. Do you have any other ideas about this?

    My getter method looks like this:
    @OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER)
    @JoinColumn(name = “RC_ID”)
    public Set getConditionalCriterias() {
    final Set conditionalCriterias = new HashSet(); final ConditionalCriteriaCentral condCriteria = new ConditionalCriteriaCentral();
    condCriteria.setName(“TEST”);
    condCriteria.setValue(“TEST_VALUE”);
    conditionalCriterias.add(condCriteria);
    return conditionalCriterias;
    }
    Thanks

    Monday, September 13, 2010 at 5:34 pm | Permalink
  2. Priyatam wrote:

    What is your persist/save operation? It’s not clear why getConditionalCriterias() is creating a new set every time. Also, while adding a new object to a collection, make sure you are setting the object references both ways. See addBar() method above.

    Tuesday, September 14, 2010 at 3:28 pm | Permalink

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*