True Confessions of a Hibernate User

by Bill Siggelkow

If you are using Hibernate for your persistence layer, debugging can be a challenge. I recently had a problem that was driving me nuts ...


In short, I was stepping through code in my IDE's debugger. I had traced the problem to a query that I was executing with Hibernate. An exception was thrown when I attempted the query ... here's the stacktrace.


java.lang.ClassCastException
net.sf.hibernate.type.LongType.set(LongType.java:28)
net.sf.hibernate.type.NullableType.nullSafeSet(NullableType.java:48)
net.sf.hibernate.type.NullableType.nullSafeSet(NullableType.java:35)
net.sf.hibernate.persister.EntityPersister.dehydrate(EntityPersister.java:403)
net.sf.hibernate.persister.EntityPersister.insert(EntityPersister.java:521)
net.sf.hibernate.persister.EntityPersister.insert(EntityPersister.java:498)
net.sf.hibernate.impl.ScheduledInsertion.execute(ScheduledInsertion.java:28)
net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2362)
net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2316)
net.sf.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:1813)
net.sf.hibernate.impl.SessionImpl.getQueries(SessionImpl.java:1507)
net.sf.hibernate.impl.SessionImpl.find(SessionImpl.java:1472)
net.sf.hibernate.impl.QueryImpl.list(QueryImpl.java:45)


My first reaction was to analyze what was wrong with the query. I checked and found nothing wrong. The ClassCastException indicated that I had some incompatability in a Hibernate mapping file ... this deduction was accurate.


The problem, however, was not with the object that I was performing the query. The problem was related to the mapping of a different object that I had inserted into the database earlier in the the life of this particular transaction. Two things clued me in -- first, on inspection, the stack trace indicates that the error was on EntityPersister.insert(). Second, I turned "show SQL" on with the following Hibernate configuration setting:


<property name="hibernate.show_sql">true</property>

Looking at the logs out of Tomcat clearly showed that the error occured when executing an SQL insert statement.


What was happening was that Hibernate had not flushed the insert to the database. It was not until I issued a query that Hibernate attempted to execute the insert statement. Once I realized that the offending object was not the one being queried but the one being inserted, I quickly located the problem in my mapping XML file. I had incorrectly defined the type of a property as a Long instead of a String. A quick change to the XML file and the problem was solved.


A few lessons I learned here:


  • Turn on Show SQL when debugging with Hibernate

  • Trust the log file

  • Don't just scan the stack trace, read it carefully



In hindsight the problem is, of course, obvious -- in the words of the great poet Homer -- Doh!



5 Comments

bernardo.roubach
2004-09-15 16:23:04
what if...
Hi there!


Nice to see someone had a problem similar to
mine... but what if the debugging of hibernate
is on, your mapping is simply flawless and
the stack trace simply do not show you anything
helpful? :D


Ok, I admit that the flawless part can be wrong..
:D But where is the problem?


This is the problem if someone is interested:
I have an entity A that maps to another entity
B through a varchar field (primary key of B is
varchar). The problem comes up when I try to
persit the entity A. The stack trace says that
it is trying to persist the field of the entity A
as a Long, when, actually it is a String that is
used to reference entity B.


Anyone?


[]s
Bernardo

BillSiggelkow
2004-09-16 07:25:48
what if...
This sounds like exactly like a mapping issue. If you've checked and you don't see the problem get another pair of eyes to take a look. If that fails, don't spend too much time guessing--Hibernate's open source--just pull out your handy-dandy debugger.


Good Luck,
Bill

bernardo.roubach
2004-09-20 13:17:07
re: what if...
Hi there!


I should always bug myself before bugging hibernate... :) I made what you suggested
and found out that the problem was somewhere
else and had nothing to do with the thing
I thought it was... :)


Perhaps the messages hibernate shows are
not very clear or not enough.. I will start
using this practice of reading the source
code more often.. And that's the beauty
of open source, isn't it? :D


[]s
Bernardo

ddkilzer
2004-10-05 09:24:11
Use Xdoclet

I strongly encourage you to look at Xdoclet to solve future mapping issues. It puts the mapping metadata inside your Java classes using specially-formatted Javadoc, and you'll never have a mapping issue (related to the incorrect type) again.


http://xdoclet.sourceforge.net/xdoclet/index.html


You may also integrate the generation of the mapping files using Ant tasks.


GaryRowe
2005-07-03 02:21:30
Good advice
After spending an entire evening trying to figure out why my commit() wouldn't work, I finally tracked the problem down to a StringType ClassCastException.


It was in the mapping files, and I will be using XDoclet in the future to handle these mapping files in addition to automated generation of entity classes.


This article pointed me immediately to the problem, forced me to use fresh eyes and the (now glaringly obvious) problem leapt off the screen and made me cry out - D'oh!


Another entry for the unit tests... :)