A follow-up. This problem is more evident when you have hibernate-validator on the classpath whereby it will register BeanValidationEventListener described here: http://docs.jboss.org/hibernate/validator/5.1/reference/en-US/html/validator-integration.html#validator-checkconstraints-orm-hibernateevent
If Hibernate Validator is present in the classpath, Hibernate Annotations (or Hibernate EntityManager) will use it transparently. To avoid validation even though Hibernate Validator is in the classpath set javax.persistence.validation.mode to none.
When you have an Entity containing a Collection with @NotEmpty like so:
@NotEmpty(message="User must have at least one role assigned.")
@ManyToMany( targetEntity=Role.class, cascade=CascadeType.ALL )
@JoinTable( name="identity_roles", joinColumns=@JoinColumn(name="identity_id"), inverseJoinColumns=@JoinColumn(name="role_id") )
private Set<Role> roles = new HashSet<Role>();
SampleEntity sampleEntity;
sampleEntity.getRoles().add(someRole);
sampleEntityDao.save(sampleEntity);
The transient Entity, even if the collection is populated and non-empty, will be temporarily empty as part of the merge copying process. This is where the pre-insert which will cause a ConstraintViolationException in this case. If the merge process weren't interrupted (javax.persistence.validation.mode=none) the collection will end up not empty and there will be no problem.
So it is really an unfortunate combination of the merge process (described in above comment with DefaultMergeEventListener, AbstractType, and CollectionType) along with BeanValidationEventListener and the @NotEmpty constraint. It is almost as if @NotEmpty might sometimes need to be checked at a different time than EventType.PRE_INSERT.
I'm unsure if this would make it a hibernate-validator bug or a hibernate-core bug.
|