<?xml version="1.0" encoding="UTF-8"?>
<!--
	~ JBoss, Home of Professional Open Source
	~ Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual contributors
	~ by the @authors tag. See the copyright.txt in the distribution for a
	~ full listing of individual contributors.
	~
	~ Licensed under the Apache License, Version 2.0 (the "License");
	~ you may not use this file except in compliance with the License.
	~ You may obtain a copy of the License at
	~ http://www.apache.org/licenses/LICENSE-2.0
	~ Unless required by applicable law or agreed to in writing, software
	~ distributed under the License is distributed on an "AS IS" BASIS,
	~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	~ See the License for the specific language governing permissions and
	~ limitations under the License.
-->
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % BOOK_ENTITIES SYSTEM "../hv.ent">
%BOOK_ENTITIES;
]>
<chapter id="validator-integration">
  <title>Integration with other frameworks</title>

  <para>Hibernate Validator is intended to be used to implement multi-layered
  data validation, where constraints are expressed in a single place (the
  annotated domain model) and checked in various different layers of the
  application.</para>

  <section id="validator-osgi">
    <title>OSGi</title>

    <para>The Hibernate Validator jar file is conform to the OSGi specification
    and can be used within any OSGi container. The following lists represent the
    packages imported and exported by Hibernate Validator. The classes within the
    exported packages are considered part of Hibernate Validator public API.</para>

    <tip>
        <para>The Java Service Provider mechanism used by Bean Validation to automatically
        discover validation providers doesn't work in an OSGi environment. To solve this,
        you have to provide a custom <classname>ValidationProviderResolver</classname>. See
        <xref linkend="section-validation-provider-resolver"/></para>
    </tip>

    <itemizedlist>
        <title>Exported packages</title>
        <listitem>
            <para><package>org.hibernate.validator</package></para>
        </listitem>
        <listitem>
            <para><package>org.hibernate.validator.constraints</package></para>
        </listitem>
        <listitem>
            <para><package>org.hibernate.validator.cfg</package></para>
        </listitem>
        <listitem>
            <para><package>org.hibernate.validator.cfg.context</package></para>
        </listitem>
        <listitem>
            <para><package>org.hibernate.validator.cfg.defs</package></para>
        </listitem>
        <listitem>
            <para><package>org.hibernate.validator.group</package></para>
        </listitem>
        <listitem>
            <para><package>org.hibernate.validator.messageinterpolation</package></para>
        </listitem>
        <listitem>
            <para><package>org.hibernate.validator.method</package></para>
        </listitem>
        <listitem>
            <para><package>org.hibernate.validator.method.metadata</package></para>
        </listitem>
        <listitem>
            <para><package>org.hibernate.validator.resourceloading</package></para>
        </listitem>
    </itemizedlist>

    <itemizedlist>
        <title>Imported packages</title>
        <listitem>
            <para><package>javax.persistence.*</package>, [2.0.0,3.0.0), optional</para>
        </listitem>
        <listitem>
            <para><package>javax.validation.*</package>, [1.0.0,2.0.0)</para>
        </listitem>
        <listitem>
            <para><package>javax.xml.*</package></para>
        </listitem>
        <listitem>
            <para><package>org.xml.sax.*</package></para>
        </listitem>
        <listitem>
            <para><package>org.jboss.logging.*</package>, [3.1.0,4.0.0)</para>
        </listitem>
        <listitem>
            <para><package>org.joda.time.*</package>, [1.6.0,2.0.0), optional</para>
        </listitem>
        <listitem>
            <para><package>org.jsoup.*</package>, [1.5.2,2.0.0), optional</para>
        </listitem>
    </itemizedlist>
  </section>

  <section id="validator-checkconstraints-db">
    <title>Database schema-level validation</title>

    <para>Out of the box, Hibernate Annotations (as of Hibernate 3.5.x) will
    translate the constraints you have defined for your entities into mapping
    metadata. For example, if a property of your entity is annotated
    <literal>@NotNull</literal>, its columns will be declared as <literal>not
    null</literal> in the DDL schema generated by Hibernate.</para>

    <para>If, for some reason, the feature needs to be disabled, set
    <literal>hibernate.validator.apply_to_ddl</literal> to
    <literal>false</literal>. See also <xref
    linkend="table-builtin-constraints" />.</para>

    <para>You can also limit the DDL constraint generation to a subset of the
    defined constraints by setting the property
    <property>org.hibernate.validator.group.ddl</property>. The property
    specifies the comma-separated, fully specified class names of the groups a
    constraint has to be part of in order to be considered for DDL schema
    generation.</para>
  </section>

  <section id="validator-checkconstraints-orm">
    <title>ORM integration</title>

    <para>Hibernate Validator integrates with both Hibernate and all pure Java
    Persistence providers.</para>

    <tip>
      <para>When lazy loaded associations are supposed to be validated it is
      recommended to place the constraint on the getter of the association.
      Hibernate replaces lazy loaded associations with proxy instances which
      get initialized/loaded when requested via the getter. If, in such a
      case, the constraint is placed on field level the actual proxy instance
      is used which will lead to validation errors.</para>
    </tip>

    <section id="validator-checkconstraints-orm-hibernateevent">
      <title>Hibernate event-based validation</title>

      <para>Hibernate Validator has a built-in Hibernate event listener -
      <ulink
      url="http://fisheye.jboss.org/browse/Hibernate/core/trunk/annotations/src/main/java/org/hibernate/cfg/beanvalidation/BeanValidationEventListener.java"><classname>org.hibernate.cfg.beanvalidation.BeanValidationEventListener</classname></ulink>
      - which is part of Hibernate Annotations (as of Hibernate 3.5.x).
      Whenever a <literal>PreInsertEvent</literal>,
      <literal>PreUpdateEvent</literal> or
      <classname>PreDeleteEvent</classname> occurs, the listener will verify
      all constraints of the entity instance and throw an exception if any
      constraint is violated. Per default objects will be checked before any
      inserts or updates are made by Hibernate. Pre deletion events will per
      default not trigger a validation. You can configure the groups to be
      validated per event type using the properties
      <property>javax.persistence.validation.group.pre-persist</property>,
      <property>javax.persistence.validation.group.pre-update</property> and
      <property>javax.persistence.validation.group.pre-remove</property>. The
      values of these properties are the comma-separated, fully specified
      class names of the groups to validate. <xref
      linkend="example-beanvalidationeventlistener-config" /> shows the
      default values for these properties. In this case they could also be
      omitted.</para>

      <para>On constraint violation, the event will raise a runtime
      <classname>ConstraintViolationException</classname> which contains a set
      of <literal>ConstraintViolation</literal>s describing each
      failure.</para>

      <para>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
      <property>javax.persistence.validation.mode</property> to
      <constant>none</constant>.</para>

      <para><note>
          <para>If the beans are not annotated with validation annotations,
          there is no runtime performance cost.</para>
        </note></para>

      <para>In case you need to manually set the event listeners for Hibernate
      Core, use the following configuration in
      <literal>hibernate.cfg.xml</literal>:</para>

      <example id="example-beanvalidationeventlistener-config">
        <title>Manual configuration of
        <classname>BeanValidationEvenListener</classname></title>

        <programlisting language="XML" role="XML">&lt;hibernate-configuration&gt;
    &lt;session-factory&gt;
       ...
       &lt;property name="javax.persistence.validation.group.pre-persist"&gt;javax.validation.groups.Default&lt;/property&gt;
       &lt;property name="javax.persistence.validation.group.pre-update"&gt;javax.validation.groups.Default&lt;/property&gt;
       &lt;property name="javax.persistence.validation.group.pre-remove"&gt;&lt;/property&gt;
       ...
       &lt;event type="pre-update"&gt;
         &lt;listener class="org.hibernate.cfg.beanvalidation.BeanValidationEventListener"/&gt;
       &lt;/event&gt;
       &lt;event type="pre-insert"&gt;
         &lt;listener class="org.hibernate.cfg.beanvalidation.BeanValidationEventListener"/&gt;
       &lt;/event&gt;
       &lt;event type="pre-delete"&gt;
         &lt;listener class="org.hibernate.cfg.beanvalidation.BeanValidationEventListener"/&gt;
       &lt;/event&gt;
    &lt;/session-factory&gt;
&lt;/hibernate-configuration&gt;</programlisting>
      </example>
    </section>

    <section>
      <title>JPA</title>

      <para>If you are using JPA 2 and Hibernate Validator is in the classpath
      the JPA2 specification requires that Bean Validation gets enabled. The
      properties
      <property>javax.persistence.validation.group.pre-persist</property>,
      <property>javax.persistence.validation.group.pre-update</property> and
      <property>javax.persistence.validation.group.pre-remove</property> as
      described in <xref
      linkend="validator-checkconstraints-orm-hibernateevent" /> can in this
      case be configured in <filename>persistence.xml</filename>.
      <filename>persistence.xml</filename> also defines a node validation-mode
      which can be set to <constant>AUTO</constant>,
      <constant>CALLBACK</constant>, <constant>NONE</constant>. The default is
      <constant>AUTO</constant>.</para>

      <para>In a JPA 1 you will have to create and register Hibernate
      Validator yourself. In case you are using Hibernate EntityManager you
      can add a customized version of the
      <classname>BeanValidationEventListener</classname> described in <xref
      linkend="validator-checkconstraints-orm-hibernateevent" /> to your
      project and register it manually.</para>
    </section>
  </section>

  <section id="section-presentation-layer">
    <title>Presentation layer validation</title>

    <para>When working with JSF2 or <productname>JBoss Seam</productname> and
    Hibernate Validator (Bean Validation) is present in the runtime
    environment validation is triggered for every field in the application.
    <xref linkend="example-jsf2" /> shows an example of the f:validateBean tag
    in a JSF page. For more information refer to the Seam documentation or the
    JSF 2 specification.</para>

    <example id="example-jsf2">
      <title>Usage of Bean Validation within JSF2</title>

      <programlisting>&lt;h:form&gt;
  <emphasis role="bold">&lt;f:validateBean&gt;</emphasis>
    &lt;h:inputText value=”#{model.property}” /&gt;
    &lt;h:selectOneRadio value=”#{model.radioProperty}” &gt; ... &lt;/h:selectOneRadio&gt;
    &lt;!-- other input components here --&gt;
  <emphasis role="bold">&lt;/f:validateBean&gt;</emphasis>
&lt;/h:form&gt;
</programlisting>
    </example>

    <tip>
      <para>The integration between JSF 2 and Bean Validation is described in
      the "Bean Validation Integration" chapter of <ulink
      url="http://jcp.org/en/jsr/detail?id=314">JSR-314</ulink>. It is
      interesting to know that JSF 2 implements a custom MessageInterpolator
      to ensure ensure proper localization. To encourage the use of the Bean
      Validation message facility, JSF 2 will per default only display the
      generated Bean Validation message. This can, however, be configured via
      the application resource bundle by providing the following configuration
      (<parameter>{0}</parameter> is replaced with the Bean Validation message
      and <parameter>{1}</parameter> is replaced with the JSF component
      label):</para>

      <programlisting>javax.faces.validator.BeanValidator.MESSAGE={1}: {0}</programlisting>

      <para>The default is:</para>

      <programlisting>javax.faces.validator.BeanValidator.MESSAGE={0}</programlisting>
    </tip>
  </section>
</chapter>
