Blog

Using the unsaved-value attribute to prevent TransientObjectExceptions in Hibernate

09 Aug, 2006

We ran into a TransientObjectException in our Hibernate-enabled code. At first the exception was very hard to reproduce and only occured in very rare cases. Sometimes during our integration tests and sometimes during our smoke tests.
We tried just about everything to find out why Hibernate interpreted the relevant objects as being unsaved (ie transient) even though we verified that they were indeed saved in a previous Hibernate Session by looking at the sql logging.
It turns out that Hibernate does not see the diffference between the values “0” and “null” when looking at the ID property (a java.lang.Long) to check whether the object is persistent. Because our Oracle sequence starts at 0, the first object that was persisted had an ID of 0. When that object was then used in a later Session, Hibernate did not recognize that value as valid and interpreted the object as transient.
We fixed this by adding an extra unsaved-value attribute to the relevant mapping. Like so:
[code]

MY_SEQ

[/code]
That solved the problem. Whether this is a bug or a feature in Hibernate I’ll leave as an exercise for the readers 🙂

guest
6 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Lars Vonk
15 years ago

This is probably an undocumented feature.The hibernate doc says:
“unsaved-value (optional – defaults to a “sensible” value)” and “The unsaved-value attribute is almost never needed in Hibernate3.”. Well indeed almost…

Serge Beaumont
Editor
15 years ago

IMHO it is a bug. I don’t know Hibernate 3, but in 2 the unsaved value was essentially the same as whatever Java initializes an instance variable to when you don’t provide an initializer:
String blah;
would mean a null value. int initializes to 0, etcetera. A Long initialized to 0 at least breaks backwards compaltibility.

Casper Groenen
Casper Groenen
15 years ago

Maybe, you should let your sequences start at 1 (which most DBMSes do anyway).

Maarten Winkels
15 years ago

Casper, you’re probably right about using sequence numbers that start at 1 when using them for valus in a column. The tricky thing is, that when using Hibernates HiLoSequenceGenerator (too decrease load on the database when inserting a lot of records in a table with a PK based on a sequence), it uses the sequence to generate a range of numbers. The transformation maps the value of 0 to the range [ 1 – range_size+1], thus when range_size = 999, a sequnce that starts at 0 will produce the numbers [1 – 1000] first and then [1001 – 2000]. A sequence that starts at 1 will first returns numbers in the range [1001 – 2000], thus leaving a gap at the start.
In our case we mix IdGenerators, since some objects are persisted more often than others, we use simple SequenceGenerators for these types. These should be used with sequences that start at 1.

Yashashree
Yashashree
12 years ago

I am getting exception as “PersistenceException: Unable to add new object to the datastore”, when i am adding new values in one of my tables using hibernate pojo class having unsaved-value=null. Can you people tell me whether this exception is related to that unsaved-value attribute??.

Explore related posts