Friday, 28 May 2010

Switching to JPA2

I've been delaying the switch over to JPA 2 for a while - things worked fine, I'm using Hibernate anyway directly for most things and the new features of JPA 2 were not that useful for me.

Till I came around to set a custom user type, and found that with Hibernate 3.5, you can annotate the default class for it, so I could omit tagging every field that uses the custom type. Neat! So I can have a user type pojo, a user type implementation and annotate like this:

@TypeDef(
name=SomepojoUserType.TYPE,
typeClass=SomepojoUserType.class,
defaultForType=Somepojo.class
)
That requires Hibernate 3.5 though, so I did that - yet, 3.5 required JPA2, so I thought what the hell, here we go, time to give it a shot.

As expected, after updating, all my unit tests fail. What I see is this:

org.hibernate.HibernateException: increment size cannot be less than 1
at org.hibernate.id.enhanced.OptimizerFactory$LegacyHiLoAlgorithmOptimizer.(OptimizerFactory.java:336)

Quick search didn't produce something useful, so I went and checked the source code. Seems that they switched from a simple sequence generator to a hilo generator as default, and somewhere I miss the property "max_lo", which seems to be "0". Another quick search is equally inconclusive, there seems to be no way to configure that.

After half a day of searching and trying around, I finally figure out that the problem is in the SequenceGenerator annotation I'm using:

@SequenceGenerator(name="seq", sequenceName="seq_name", allocationSize=1)

Now I did it that way to avoid having holes in my pks... why waste perfectly good numbers by jumping ahead? I kept a performance test for later in the queue, but figured that it wouldn't become a problem for quite a while.

Now the hi/lo generator that Hibernate introduced as the new default seems to be taking the allocation size as base for the max_lo property computation, like max_lo = allocationSize - 1. Which results in "0", which blows it up. Turning that number up brought things back to working state.

That's it for now, let's see what other surprises JPA2 / Hibernate have in store for me.

1 comment:

  1. Thanks for posting this, saved me some time.

    The slight problem is that there will be different behaviour with sequences in other providers (OpenJPA, TopLink) if you set allocationSize=2, since I assume they do not subtract 1 like Hibernate.

    I looked up the Hibernate bugs that prompted the change, but quickly got lost in all the esoteric discussions.

    Mik

    ReplyDelete