This post originated from an RSS feed registered with Java Buzz
by Chris Winters.
Original Post: Save five minutes: careful with auto-implementing Hibernate Interceptors
Feed Title: cwinters.com
Feed URL: http://www.cwinters.com/search/registrar.php?domain=jroller.com®istrar=sedopark
Feed Description: Chris Winters on Java, programming and technology, usually in that order.
I'm writing this to stick a seed in your brain that will hopefully
flower and save you five or ten minutes debugging if you ever run into
the same issue. (Plus I wanted an excuse to use lots of screenshots.)
The problem: after creating a Hibernate Interceptor in IntelliJ IDEA
none of your object updates work.
I use IDEA to write
all my Java. I love IDEA so much that I wish I could use it for
Perl. (I think if good Perl people had IDEA they'd be without a doubt the most
productive programmers on the planet and would eventually take over
the world with sigils. And it would be good.)
One of the standard IDE shortcuts in IDEA allows you to create a
file of a particular type:
Each of the entries in the menu matches a file template in the
system. You can add new file templates and use (I think) Velocity tags to ensure
the passively generated file has some useful data -- it's in the right
package, etc. Since we don't have a 'Hibernate Interceptor' type we
just want a normal Java class and choose 'Class', after which we input
the name:
This creates the simplest class possible, although you'll notice
I've customized the template with my name + email plus the standard
company copyright language. (IDEA nicely folds this up for us -- it's
lines 1-10.)
Next, we just type in 'implements Interceptor' after the class
name. IDEA is smart enough to know what 'Interceptor' classes we have
in our project or any of the associated libraries, and makes them
available with an 'Alt-Enter'.
We choose 'net.sf.hibernate.Interceptor' and IDEA puts it in our
import list for us. It also redlines the entire class declaration
because we have unimplemented methods in a concrete class:
We hit 'Ctrl-I' to have IDEA tell us what methods we need to
implement. The next screenshot shows the methods from the single
parent 'Interceptor', but IDEA is smart enough to find unimplemented
methods from both other interfaces or parent abstract classes, but
also from their parents.
IDEA will generate empty implementations for you. The
implementation depends on the return type -- a 'boolean' return will
have a single statement 'return false', an object return a 'return
null', an array 'return new arraytype[0]':
The empty array type is where we get into trouble. Here we see
where, in the empty implementation for 'findDirty()' which returns an
int array:
Most of the time when you implement a Hibernate interceptor you
only want to actually do something in one or two of the methods like
'onSave()'. So you'll probably leave the empty implementation
alone. And that's the problem -- if Hibernate gets back an empty array
(vs null) it assumes nothing is dirty and doesn't perform any
updates. I'm confident in declaring that this is not what you want. Of
course, the fix is easy -- just replace the empty int array with
'null', which I'll gratuitously show: