Here are more detailed sources about the behavior you have.
According JPA 2 specification (page 102)
If the set of ConstraintViolation objects returned by the validate method is not
empty, the persistence provider must throw the javax.validation.ConstraintViolationException containing a reference to the returned set of ConstraintViolation objects, and
must mark the transaction for rollback.
And from the hibernate doc
If an entity is found to be invalid, the list of constraint violations is propagated by the ConstraintViolationException which exposes the set of ConstraintViolations.
This exception is wrapped in a RollbackException when the violation
happens at commit time. Otherwise the ConstraintViolationException is
returned [by Hibernate Validator] (for example when calling flush().)
Additionally, from jpa 2 specs (page 101)
By default, the default Bean Validation group (the group Default) will be validated upon the pre-persist and pre-update lifecycle validation events
Putting all of this together, I'm little confused because it seems to me that the behavior of HibernatePersistenceProvider doesn't follow the JPA 2 specs since:
- validation must be performed on "pre-presist"
- persistence provider MUST throw ConstraintViolationException
And obviously, in your case the ConstraintViolationException
is not thrown when persist
is called (and when using HibernatePersistenceProvider).
So according my understanding and to answer your question :
- eclipselink is right
- hibernate is wrong
(note: I hope that someone else can confirm or disagree with my analysis)
IMPORTANT EDIT
I was confused with my own conclusion. So I tried to reproduce myself the behavior described by the OP and I was unable to reproduce this behavior immediately.
What I did was really similar to what the OP is describing:
- setup a little project, with one entity with a
@NotNull
field.
- trying to persist() an instance with null for
@NotNull
field in a simple test.
- asserting that the
persist()
operation throw a javax.validation.ConstraintViolationException
+ mark the transaction as rollback only
- doing this when using eclipselink as persistence provider --> successful
- doing this when using hibernate as persistence provider --> successful
The major difference between my test and the test described the OP was the id generation.
In my successful test, I was using a simple @GeneratedValue
.
After changing the id generation strategy to :
@GeneratedValue(strategy = GenerationType.TABLE,
generator = "NAME_MUST_NOT_BE_NULL_ID_GENERATOR")
@TableGenerator(name = "NAME_MUST_NOT_BE_NULL_ID_GENERATOR",
pkColumnValue = "NAME_MUST_NOT_BE_NULL_ID")
I found the exact behavior describe by the OP :
- a
javax.validation.ConstraintViolationException
thrown by persist()
when using eclipselink.
- no exception at all thrown by
persist()
when using hibernate.
So, when using Hibernate + strategy = GenerationType.TABLE
: the behavior is different. I'm quite sure it's not following JPA2 specifications.