Friday, November 06, 2009

JPA Myth: EclipseLink and Hibernate are compatible. Not true: Hibernate does NOT follow the JPA Spec

Please take a look at the Hibernate JIRA issue EJB-441, seen it?

Now, please tell me if this is correct:

According to Gavin King (author of Hibernate) the JPA spec the @Column(nullable=false) is just a schema generation hint, and therefore JPA implementations should NOT use it for object level validation.

I think that means that if an entity object with a null property marked with the @Column(nullable=false) is persisted using entityManager.persist() it should crash with a java.sql.SQLException as the root exception, thrown when the "INSERT" statement failed after it was sent to the database by the JDBC driver (as it happens in EclipseLink), and not because some implementation specific mechanism "pre-validated" it and prevented it from reaching the database (as it happens in Hibernate thanks to org.hibernate.engine.Nullability.checkNullability).

Is that correct? Because I don’t know anymore!

Lets say that is correct, does that means that the following is correct too?:

Validation should be entirely the responsibility of the JSR-303, and the properties of an entity should only be checked for nullability before sending to the database if a JSR-303 implementation is there to indicate that.

Is that true? And if it is, then:

What is exactly the difference between @Basic(optional=true) and @Column(nullable=true)? What happens when this 2 are applied to the same property, but they contradict each other? (As in : @Basic(optional=false) and @Column(nullable=true) or in @Basic(optional=true) and @Column(nullable=false)

I could not find a statisfactory answer in the spec documentation, would anyone be so kind as to resolve this issue? Because it Hibernate Forums they have decided that the way to deal with this inconsistencies and contradictions in Hibernate and in the JPA standard is to plain ignore me since May of 2009.

As you can see I tried to raise the issue with 2 JIRAS, forum post and easy to reproduce unit-tests, but nothing seems to work… what should I do then?

7 comments:

Rob said...

Hmmm, in hear your frustration.

The flags are primative boolean for both @Basic.optional and @Column.nullable ... so if you do have both there is definately a chance for setting them inconsistently (as you have pointed out).

I don't think this is explicit in the JPA spec so you could try the JPA spec emailing list as an option.

For what it's worth I've just looked at this for Ebean ORM and ... instead think it better that if either one is effectively nullable=true ... then that is what is used (aka implying that someone changed it from the default value explicitly). Then the DDL and persist behaviour is consistent.

Note that this sort of issue will also occur with the new Bean Validation annotations. My current thinking is that if there is a @NotNull that should be equivilent to setting nullable=false.

Good luck anyway :)

Cheers, Rob.
Ebean ORM - http://www.avaje.org

Unknown said...

I've fixed this recently when integrating Bean Validation and Hibernate. HHH-3898
Thata being said, I don't see much reason to have optional=true and nullable=false as your example shows.
It does not seem to make much sense.

Luxspes said...

Hi Emmanuel!

All I wanted with that example was to find a way to turn off org.hibernate.engine.Nullability.checkNullability. Gavin said that nullable=true was only a schema generation hint and optional=true was for object level validation, based on that I thought then: "optional=true and nullable=false" should "turn off" org.hibernate.engine.Nullability.checkNullability (optional=true) but keep the field as null in the database (nullable=false).

Shouldnt it have that effect?

Unknown said...

Frankly at the time the spec was a bit unclear and it was not wo risk to disable the in memory null checking in Hibernate.
Hence my decision from a few years back.

Luxspes said...

Ok,but.. hmmmm, is the spec clear now? Because if what Gavin said is accurate (that the spec says that nullable=true was only a schema generation hint and optional=true was for object level validation) then why did you add a general configuration flag instead of making it possible to use "optional=true and nullable=false" to disable org.hibernate.engine.Nullability.checkNullability individualy?

Luxspes said...

I mean, of course I like the fact that now I can turn off org.hibernate.engine.Nullability.checkNullability, but... I think using optional=true for this would have given it a purpose... now it is IMO even more redundant (and useless?)

Sara Reid said...

Eclipse and Hibernate are poster children for Open Source. Many developers want to integrate the two of them, and James Elliott has written on this topic. James discusses the myriad of Eclipse plugins available for Hibernate, how to set them up, and how they work.

nahrungsergänzung