Odd Hibernate Issue in Grails

Posted by jt - 27/07/10 at 10:07 am

Ran into an odd error with Hibernate under Grails today. I’m working on an integration with a legacy system and using JPA annotated classes. This typically works pretty well.

In Grails on saving an object, I was getting this error:

org.hibernate.HibernateException: identifier of an instance  foo was altered from 1 to 0

In the code, I was not doing anything unusual. Just something like ‘new Foo(bar: ‘blah).save(flush:true)

I spent a few hours working on this, thinking something was off with the annotations on the source class.

My setter was like this:

    public void setFooId(Integer fooId) {
        fooId = fooId==null?0:fooId;
    }

I think it was auto-generated by the IDE. Turns out core problem was with a missing ‘this’ on the property in the setter. Changing to:

    public void setFooId(Integer fooId) {
        this.fooId = fooId==null?0:fooId;
    }

Kind of a misleading error message. Hopefully this post saves someone else a bit of time in the future!

Share/Save/Bookmark

One Response to “Odd Hibernate Issue in Grails”

  1. jswaff says:
    August 4th, 2010 at 7:33 am

    I’m fairly sure the setter was not IDE generated. If it were it would simply be “this.foodId = fooId;” . Just a simple shadowing error with an non-obvious error message (which does make sense though).

    The reason for the ternary conditional is that this.foodId is a primitive. If the field from the datasource is null Hibernate will give you a “Null value was assigned to a property of primitive type setter.” OTOH, simple JDBC will return the default value for the primitive type (0 for ints).

    An alternative solution would be to use wrapper classes in place of the primitives. The consequence of that is you’d have to deal with the possibility of null values being returned from the getters, or put a similar conditional in to ensure that doesn’t happen.

    Of course, in Groovy / GORM *everything* is an object. :)

Leave a Reply