<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~ Hibernate, Relational Persistence for Idiomatic Java
  ~
  ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
  ~ indicated by the @author tags or express copyright attribution
  ~ statements applied by the authors.  All third-party contributions are
  ~ distributed under license by Red Hat Middleware LLC.
  ~
  ~ This copyrighted material is made available to anyone wishing to use, modify,
  ~ copy, or redistribute it subject to the terms and conditions of the GNU
  ~ Lesser General Public License, as published by the Free Software Foundation.
  ~
  ~ This program is distributed in the hope that it will be useful,
  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  ~ or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
  ~ for more details.
  ~
  ~ You should have received a copy of the GNU Lesser General Public License
  ~ along with this distribution; if not, write to:
  ~ Free Software Foundation, Inc.
  ~ 51 Franklin Street, Fifth Floor
  ~ Boston, MA  02110-1301  USA
  -->
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="additionalmodules">
  <title>Additional modules</title>

  <para>Hibernate Core also offers integration with some external
  modules/projects. This includes Hibernate Validator the reference
  implementation of Bean Validation (JSR 303) and Hibernate Search. </para>

  <section>
    <title>Bean Validation</title>

    <para>Bean Validation standardizes how to define and declare domain model
    level constraints. You can, for example, express that a property should
    never be null, that the account balance should be strictly positive, etc.
    These domain model constraints are declared in the bean itself by
    annotating its properties. Bean Validation can then read them and check
    for constraint violations. The validation mechanism can be executed in
    different layers in your application without having to duplicate any of
    these rules (presentation layer, data access layer). Following the DRY
    principle, Bean Validation and its reference implementation Hibernate
    Validator has been designed for that purpose.</para>

    <para>The integration between Hibernate and Bean Validation works at two
    levels. First, it is able to check in-memory instances of a class for
    constraint violations. Second, it can apply the constraints to the
    Hibernate metamodel and incorporate them into the generated database
    schema.</para>

    <para>Each constraint annotation is associated to a validator
    implementation responsible for checking the constraint on the entity
    instance. A validator can also (optionally) apply the constraint to the
    Hibernate metamodel, allowing Hibernate to generate DDL that expresses the
    constraint. With the appropriate event listener, you can execute the
    checking operation on inserts, updates and deletes done by
    Hibernate.</para>

    <para>When checking instances at runtime, Hibernate Validator returns
    information about constraint violations in a set of
    <classname>ConstraintViolation</classname>s. Among other information, the
    <classname>ConstraintViolation</classname> contains an error description
    message that can embed the parameter values bundle with the annotation
    (eg. size limit), and message strings that may be externalized to a
    <classname>ResourceBundle</classname>.</para>

    <section>
      <title>Adding Bean Validation</title>

      <para>To enable Hibernate's Bean Validation integration, simply add a
      Bean Validation provider (preferably Hibernate Validation 4) on your
      classpath.</para>
    </section>

    <section>
      <title>Configuration</title>

      <para>By default, no configuration is necessary.</para>

      <para>The <classname>Default</classname> group is validated on entity
      insert and update and the database model is updated accordingly based on
      the <classname>Default</classname> group as well.</para>

      <para>You can customize the Bean Validation integration by setting the
      validation mode. Use the
      <literal>javax.persistence.validation.mode</literal> property and set it
      up for example in your <filename>persistence.xml</filename> file or your
      <filename>hibernate.cfg.xml</filename> file. Several options are
      possible:</para>

      <itemizedlist>
        <listitem>
          <para><literal>auto</literal> (default): enable integration between
          Bean Validation and Hibernate (callback and ddl generation) only if
          Bean Validation is present in the classpath.</para>
        </listitem>

        <listitem>
          <para><literal>none</literal>: disable all integration between Bean
          Validation and Hibernate</para>
        </listitem>

        <listitem>
          <para><literal>callback</literal>: only validate entities when they
          are either inserted, updated or deleted. An exception is raised if
          no Bean Validation provider is present in the classpath.</para>
        </listitem>

        <listitem>
          <para><literal>ddl</literal>: only apply constraints to the database
          schema when generated by Hibernate. An exception is raised if no
          Bean Validation provider is present in the classpath. This value is
          not defined by the Java Persistence spec and is specific to
          Hibernate.</para>
        </listitem>
      </itemizedlist>

      <note>
        <para>You can use both <literal>callback</literal> and
        <literal>ddl</literal> together by setting the property to
        <literal>callback, dll</literal></para>

        <programlisting language="XML" role="XML">&lt;persistence ...&gt;
  &lt;persistence-unit ...&gt;
    ...
    &lt;properties&gt;
      &lt;property name="javax.persistence.validation.mode"
                value="callback, ddl"/&gt;
    &lt;/properties&gt;
  &lt;/persistence-unit&gt;
&lt;/persistence&gt;</programlisting>

        <para>This is equivalent to <literal>auto</literal> except that if no
        Bean Validation provider is present, an exception is raised.</para>
      </note>

      <para>If you want to validate different groups during insertion, update
      and deletion, use:</para>

      <itemizedlist>
        <listitem>
          <para><literal>javax.persistence.validation.group.pre-persist</literal>:
          groups validated when an entity is about to be persisted (default to
          <classname>Default</classname>)</para>
        </listitem>

        <listitem>
          <para><literal>javax.persistence.validation.group.pre-update</literal>:
          groups validated when an entity is about to be updated (default to
          <classname>Default</classname>)</para>
        </listitem>

        <listitem>
          <para><literal>javax.persistence.validation.group.pre-remove</literal>:
          groups validated when an entity is about to be deleted (default to
          no group)</para>
        </listitem>

        <listitem>
          <para><literal>org.hibernate.validator.group.ddl</literal>: groups
          considered when applying constraints on the database schema (default
          to <classname>Default</classname>)</para>
        </listitem>
      </itemizedlist>

      <para>Each property accepts the fully qualified class names of the
      groups validated separated by a comma (,)</para>

      <example>
        <title>Using custom groups for validation</title>

        <programlisting language="XML" role="XML">&lt;persistence ...&gt;
  &lt;persistence-unit ...&gt;
    ...
    &lt;properties&gt;
      &lt;property name="javax.persistence.validation.group.pre-update"
                value="javax.validation.group.Default, com.acme.group.Strict"/&gt;
      &lt;property name="javax.persistence.validation.group.pre-remove"
                value="com.acme.group.OnDelete"/&gt;
      &lt;property name="org.hibernate.validator.group.ddl"
                value="com.acme.group.DDL"/&gt;
    &lt;/properties&gt;
  &lt;/persistence-unit&gt;
&lt;/persistence&gt;</programlisting>
      </example>

      <note>
        <para>You can set these properties in
        <filename>hibernate.cfg.xml</filename>,
        <filename>hibernate.properties</filename> or programmatically.</para>
      </note>
    </section>

    <section>
      <title>Catching violations</title>

      <para>If an entity is found to be invalid, the list of constraint
      violations is propagated by the
      <classname>ConstraintViolationException</classname> which exposes the
      set of <classname>ConstraintViolation</classname>s.</para>

      <para>This exception is wrapped in a
      <classname>RollbackException</classname> when the violation happens at
      commit time. Otherwise the
      <classname>ConstraintViolationException</classname> is returned (for
      example when calling <methodname>flush()</methodname>. Note that
      generally, catchable violations are validated at a higher level (for
      example in Seam / JSF 2 via the JSF - Bean Validation integration or in
      your business layer by explicitly calling Bean Validation).</para>

      <para>An application code will rarely be looking for a
      <classname>ConstraintViolationException</classname> raised by Hibernate.
      This exception should be treated as fatal and the persistence context
      should be discarded (<classname>EntityManager</classname> or
      <classname>Session</classname>).</para>
    </section>

    <section>
      <title>Database schema</title>

      <para>Hibernate uses Bean Validation constraints to generate an accurate
      database schema:</para>

      <itemizedlist>
        <listitem>
          <para><classname>@NotNull</classname> leads to a not null column
          (unless it conflicts with components or table inheritance)</para>
        </listitem>

        <listitem>
          <para><classname>@Size.max</classname> leads to a
          <literal>varchar(max)</literal> definition for Strings</para>
        </listitem>

        <listitem>
          <para><classname>@Min</classname>, <classname>@Max</classname> lead
          to column checks (like <code>value &lt;= max</code>)</para>
        </listitem>

        <listitem>
          <para><classname>@Digits</classname> leads to the definition of
          precision and scale (ever wondered which is which? It's easy now
          with <classname>@Digits</classname> :) )</para>
        </listitem>
      </itemizedlist>

      <para>These constraints can be declared directly on the entity
      properties or indirectly by using constraint composition.</para>

      <para>For more information check the Hibernate Validator <ulink
      url="http://docs.jboss.org/hibernate/stable/validator/reference/en-US/html/">reference
      documentation</ulink>.</para>
    </section>
  </section>

  <section>
    <title>Hibernate Search</title>

    <section>
      <title>Description</title>

      <para>Full text search engines like <productname>Apache
      Lucene</productname> are a very powerful technology to bring free
      text/efficient queries to applications. If suffers several mismatches
      when dealing with a object domain model (keeping the index up to date,
      mismatch between the index structure and the domain model, querying
      mismatch...) Hibernate Search indexes your domain model thanks to a few
      annotations, takes care of the database / index synchronization and
      brings you back regular managed objects from free text queries.
      Hibernate Search is using <ulink url="http://lucene.apache.org">Apache
      Lucene</ulink> under the cover.</para>
    </section>

    <section>
      <title>Integration with Hibernate Annotations</title>

      <para>Hibernate Search integrates with Hibernate Core transparently
      provided that the Hibernate Search jar is present on the classpath. If
      you do not wish to automatically register Hibernate Search event
      listeners, you can set
      <literal>hibernate.search.autoregister_listeners</literal> to false.
      Such a need is very uncommon and not recommended.</para>

      <para>Check the Hibernate Search <ulink
      url="http://docs.jboss.org/hibernate/stable/search/reference/en-US/html/">reference
      documentation</ulink> for more information.</para>
    </section>
  </section>
</chapter>
