2

I have a Java EE 7 web application (JSF 2.2) and JPA with EclipseLink 2.5.2, running on a GlassFish 4.1 (build 13) with Hibernate Validator 5.0.0.Final.

My purpose is to use bean validation for the enitity classes but don't want to use the provided annotations. I want to define the constrains for bean validation in XML. I have done this throw a file located in META-INF/validation.xml:

<?xml version="1.0" encoding="UTF-8"?>
<validation-config xmlns ="http://jboss.org/xml/ns/javax/validation/configuration"
                   xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation = "http://jboss.org/xml/ns/javax/validation/configuration validation-configuration-1.1.xsd">
  <constraint-mapping>
    META-INF/validation/EntityTest-constraints.xml
  </constraint-mapping>
</validation-config>

And the Constraint-File:

<?xml version="1.0" encoding="UTF-8"?>
<constraint-mappings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.1.xsd"
    xmlns="http://jboss.org/xml/ns/javax/validation/mapping" version="1.1">
  <bean class="testprojektjee7.business.test.EntityTest">
    <field name="label">
      <constraint annotation="javax.validation.constraints.Size">
        <message>3 bis 10 Zeichen!</message>
        <element name="min">3</element>
        <element name="max">10</element>
      </constraint>
    </field>
  </bean>
</constraint-mappings>

And this is the Entity-Class:

@Entity
public class EntityTest implements Serializable {

  @Id
  @GeneratedValue(strategy = javax.persistence.GenerationType.IDENTITY)
  private long id;

  private String label;

  public long getId() {
    return id;
  }

  public void setId(long id) {
    this.id = id;
  }

  public String getLabel() {
    return label;
  }

  public void setLabel(String label) {
    this.label = label;
  }
}

Everything is working fine if I use JSF to bind an input field to the label-field of the entity. In this case I get validation errors when the label is too short or too long. So the XML-Way is working with JSF.

But when I create an entity instance out of an Stateless EJB (@Stateless) and going to persist this instance throw the EntityManager I get no automatic bean validation errors. Otherwise it works when I am going to annotate the label-Attribut with the @Size annotation. So I don't know what I am doing wrong with the bean validation throw xml files because with JSF everything is working fine and the GlassFish server also logs that he found the validation.xml file and is going to parse it:

HV000007: META-INF/validation.xml found. Parsing XML based configuration.

Persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
  <persistence-unit name="TestprojektJEE7_PU" transaction-type="JTA">
    <jta-data-source>jdbc/testprojektjee7</jta-data-source>
    <class>testprojektjee7.business.test.EntityTest</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
      <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
    </properties>
  </persistence-unit>
</persistence>

Addition 1

To clarify the problem I just have done the other way and had defined an annoation at the field in the entity class. In this case I get the expected exception throw prePersist callback. Here is the stacktrace:

Caused by: javax.validation.ConstraintViolationException: Bean Validation constraint(s) violated while executing Automatic Bean Validation on callback event:'prePersist'. Please refer to embedded ConstraintViolations for details.
    at org.eclipse.persistence.internal.jpa.metadata.listeners.BeanValidationListener.validateOnCallbackEvent(BeanValidationListener.java:90)
    at org.eclipse.persistence.internal.jpa.metadata.listeners.BeanValidationListener.prePersist(BeanValidationListener.java:62)
    at org.eclipse.persistence.descriptors.DescriptorEventManager.notifyListener(DescriptorEventManager.java:748)
    at org.eclipse.persistence.descriptors.DescriptorEventManager.notifyEJB30Listeners(DescriptorEventManager.java:691)
    at org.eclipse.persistence.descriptors.DescriptorEventManager.executeEvent(DescriptorEventManager.java:229)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectClone(UnitOfWorkImpl.java:4316)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNotRegisteredNewObjectForPersist(UnitOfWorkImpl.java:4293)
    at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.registerNotRegisteredNewObjectForPersist(RepeatableWriteUnitOfWork.java:518)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(UnitOfWorkImpl.java:4235)
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.persist(EntityManagerImpl.java:496)
    at com.sun.enterprise.container.common.impl.EntityManagerWrapper.persist(EntityManagerWrapper.java:287)

I think the BeanValidationListener from org.eclipse.* only validates constraints which are present as annotations and is not looking at the constraints defined in xml files.


Addition 2

The method org.eclipse.persistence.internal.jpa.metadata.listeners.BeanValidationListener.validateOnCallbackEvent(...) gets an instance of org.hibernate.validator.internal.engine.ValidatorImpl.java. This validator implementation is ignoring the constraints defined by xml.

BUT if I get an validator instace from the EJB-Container throw @Resource annotation it validates correctly (also xml) and the instance is from the same ValidatorImpl too. I don't figured out the difference.

  • I think what you means hibernate validator does not affect database schema...I think this is not part of JPA or bean validation. it could be a specific feature of Hibernate itself. I am it works in Wildfly, but Glassfish shipped EclipseLink as JPA provider. – Hantsy Aug 17 '16 at 14:08
  • So you mean that EclipseLink does not provide the possibility to define the constraints throw xml files? As I mentioned the bean validation throw annotations are working fine with the eclipselink provider. – Flexolut IT Aug 17 '16 at 14:22
  • If it works with JSF the issue is not JSF related. I removed the tag, added [tag:eclipselink] and [tag:hibernate-validator] instead of [tag:hibernate] – Kukeltje Aug 17 '16 at 18:27
  • EclipseLInk isn't your bean validator and doesn't do bean validation itself, it only makes calls to the validator. If the validation.xml file isn't being picked up by your hibernate validator, you'll need to check its logs as to why it can only pick up or see the annotations and not the xml. It could be a packaging issue, where the validation.xml isn't picked up by the loader used for the persistence unit. – Chris Aug 22 '16 at 16:42

0 Answers0