<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<section id="Core.DatabaseConfigurationForHibernate">
  <title>Database Configuration for Hibernate</title>

  <para>As usual, it is quite simple to use our configuration XML syntax to
  configure and parametrize different Databases for eXo tables but also for
  your own use.</para>

  <section id="Core.DatabaseConfigurationForHibernate.GenericConfiguration">
    <title>Generic configuration</title>

    <para>The default DB configuration uses HSQLDB, a Java Database quite
    useful for demonstrations.</para>

    <programlisting language="xml">&lt;component&gt; 
   &lt;key&gt;org.exoplatform.services.database.HibernateService&lt;/key&gt;
   &lt;jmx-name&gt;exo-service:type=HibernateService&lt;/jmx-name&gt;
   &lt;type&gt;org.exoplatform.services.database.impl.HibernateServiceImpl&lt;/type&gt;
   &lt;init-params&gt;
      &lt;properties-param&gt;
         &lt;name&gt;hibernate.properties&lt;/name&gt;
         &lt;description&gt;Default Hibernate Service&lt;/description&gt;
         &lt;property name="hibernate.show_sql" value="false"/&gt;
         &lt;property name="hibernate.cglib.use_reflection_optimizer" value="true"/&gt;
         &lt;property name="hibernate.connection.url" value="jdbc:hsqldb:file:../temp/data/portal"/&gt;
         &lt;property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/&gt;
         &lt;property name="hibernate.connection.autocommit" value="true"/&gt;
         &lt;property name="hibernate.connection.username" value="sa"/&gt;
         &lt;property name="hibernate.connection.password" value=""/&gt;
         &lt;property name="hibernate.cache.region.factory_class" value="org.exoplatform.services.database.impl.ExoCacheRegionFactory"/&gt;
         &lt;property name="hibernate.cache.use_second_level_cache" value="true"/&gt;
         &lt;property name="hibernate.cache.use_query_cache" value="true"/&gt;
         &lt;property name="hibernate.hbm2ddl.auto" value="update"/&gt;
         &lt;property name="hibernate.c3p0.min_size" value="5"/&gt;
         &lt;property name="hibernate.c3p0.max_size" value="20"/&gt;
         &lt;property name="hibernate.c3p0.timeout" value="1800"/&gt;
         &lt;property name="hibernate.c3p0.max_statements" value="50"/&gt;
      &lt;/properties-param&gt;
   &lt;/init-params&gt;
&lt;/component&gt;</programlisting>

    <para>In the init parameter section, we define the default hibernate
    properties including the DB URL, the driver and the credentials in
    use.</para>

    <para>For any portals that configuration can be overridden, depending on
    the needs of your environment.</para>

    <para>Several databases have been tested and can be used in
    production....which is not the case of HSQLDB, HSQLDB can only be used for
    development environments and for demonstrations.</para>
  </section>

  <section id="Core.DatabaseConfigurationForHibernate.ExampleDBConfiguration">
    <title>Example DB configuration</title>

    <para>For MySQL</para>

    <programlisting language="xml">&lt;component&gt; 
   &lt;key&gt;org.exoplatform.services.database.HibernateService&lt;/key&gt;
   &lt;jmx-name&gt;database:type=HibernateService&lt;/jmx-name&gt;
   &lt;type&gt;org.exoplatform.services.database.impl.HibernateServiceImpl&lt;/type&gt;
   &lt;init-params&gt;
      &lt;properties-param&gt;
         &lt;name&gt;hibernate.properties&lt;/name&gt;
         &lt;description&gt;Default Hibernate Service&lt;/description&gt;
         &lt;property name="hibernate.show_sql" value="false"/&gt;
         &lt;property name="hibernate.cglib.use_reflection_optimizer" value="true"/&gt;
         &lt;property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/exodb?relaxAutoCommit=true&amp;amp;amp;autoReconnect=true&amp;amp;amp;useUnicode=true&amp;amp;amp;characterEncoding=utf8"/&gt;
         &lt;property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/&gt;
         &lt;property name="hibernate.connection.autocommit" value="true"/&gt;
         &lt;property name="hibernate.connection.username" value="sa"/&gt;
         &lt;property name="hibernate.connection.password" value=""/&gt;
         &lt;property name="hibernate.cache.region.factory_class" value="org.exoplatform.services.database.impl.ExoCacheRegionFactory"/&gt;
         &lt;property name="hibernate.cache.use_second_level_cache" value="true"/&gt;
         &lt;property name="hibernate.cache.use_query_cache" value="true"/&gt;
         &lt;property name="hibernate.hbm2ddl.auto" value="update"/&gt;
         &lt;property name="hibernate.c3p0.min_size" value="5"/&gt;
         &lt;property name="hibernate.c3p0.max_size" value="20"/&gt;
         &lt;property name="hibernate.c3p0.timeout" value="1800"/&gt;
         &lt;property name="hibernate.c3p0.max_statements" value="50"/&gt;
       &lt;/properties-param&gt;
   &lt;/init-params&gt;
&lt;/component&gt;</programlisting>
  </section>

  <section id="Core.DatabaseConfigurationForHibernate.HibernateCaching">
    <title>Caching configuration</title>

    <para>Hibernate caching is enabled by default by this parameters</para>

    <programlisting language="xml">
&lt;property name="hibernate.cache.region.factory_class" value="org.exoplatform.services.database.impl.ExoCacheRegionFactory"/&gt;
&lt;property name="hibernate.cache.use_second_level_cache" value="true"/&gt;
&lt;property name="hibernate.cache.use_query_cache" value="true"/&gt;
    </programlisting>

    <para>Hibernate caching parameters are well described in hibernate
    documentation. There is no forced injection of eXo cache provider anymore.
    It's usage can be configured via standard hibernate properties (in our
    xml) just like any other hibernate settings.</para>

    <para>Also it is possible to configure size of eXoCache instances via
    cache service configuration. Every region (eXoCache instance) created by
    RegionFactory has it's own prefix depending on it's type. All prefixes
    are: <programlisting language="xml">
ExoCacheRegionFactory-Entity-
ExoCacheRegionFactory-NaturalId-
ExoCacheRegionFactory-Collection-
ExoCacheRegionFactory-QueryResults-
ExoCacheRegionFactory-Timestamps-
    </programlisting> So, names of eXoCache instances will look like
    "ExoCacheRegionFactory-Entity-org.exoplatform.services.organization.impl.GroupImpl",
    etc. Details about cache service configuration can be found in <link
    linkend="Kernel.Cache"> eXo Cache section</link>.</para>

    <warning>
      Hibernate's second level cache is enabled by default. In case if you want to turn it off you must explicitly set property "hibernate.cache.use_second_level_cache" to false.
    </warning>
  </section>

  <section id="Core.DatabaseConfigurationForHibernate.RegisteringCustomHibernateXMLFilesIntoService">
    <title>Registering custom annotated classes and Hibernate XML files into
    the service</title>

    <para>It is possible to use the eXo hibernate service and register your
    annotated classes or hibernate hbm.xml files to leverage some add-on
    features of the service such as the table automatic creation as well as
    the cache of the hibernate session in a ThreadLocal object during all the
    request lifecycle. To do so, you just have to add a plugin and indicate
    the location of your files.</para>

    <para>Registering custom XML files can be done in this way:</para>

    <programlisting language="xml">&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
&lt;configuration&gt;
  &lt;external-component-plugins&gt;
    &lt;target-component&gt;org.exoplatform.services.database.HibernateService&lt;/target-component&gt;
    &lt;component-plugin&gt; 
      &lt;name&gt;add.hibernate.mapping&lt;/name&gt;
      &lt;set-method&gt;addPlugin&lt;/set-method&gt;
      &lt;type&gt;org.exoplatform.services.database.impl.AddHibernateMappingPlugin&lt;/type&gt;
      &lt;init-params&gt;
        &lt;values-param&gt;
          &lt;name&gt;hibernate.mapping&lt;/name&gt;
          &lt;value&gt;org/exoplatform/services/organization/impl/UserImpl.hbm.xml&lt;/value&gt;
          &lt;value&gt;org/exoplatform/services/organization/impl/MembershipImpl.hbm.xml&lt;/value&gt;
          &lt;value&gt;org/exoplatform/services/organization/impl/GroupImpl.hbm.xml&lt;/value&gt;
          &lt;value&gt;org/exoplatform/services/organization/impl/MembershipTypeImpl.hbm.xml&lt;/value&gt;
          &lt;value&gt;org/exoplatform/services/organization/impl/UserProfileData.hbm.xml&lt;/value&gt;
        &lt;/values-param&gt;
      &lt;/init-params&gt;
    &lt;/component-plugin&gt;
  &lt;/external-component-plugins&gt;  
&lt;/configuration&gt;</programlisting>

    <para>Registering custom annotated classes can be done in this way:</para>

    <programlisting language="xml">&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
&lt;configuration&gt;
  &lt;external-component-plugins&gt;
    &lt;target-component&gt;org.exoplatform.services.database.HibernateService&lt;/target-component&gt;
    &lt;component-plugin&gt; 
      &lt;name&gt;add.hibernate.annotations&lt;/name&gt;
      &lt;set-method&gt;addPlugin&lt;/set-method&gt;
      &lt;type&gt;org.exoplatform.services.database.impl.AddHibernateMappingPlugin&lt;/type&gt;
      &lt;init-params&gt;
        &lt;values-param&gt;
          &lt;name&gt;hibernate.annotations&lt;/name&gt;
          &lt;value&gt;org.exoplatform.services.organization.impl.UserProfileData&lt;/value&gt;
          &lt;value&gt;org.exoplatform.services.organization.impl.MembershipImpl&lt;/value&gt;
          &lt;value&gt;org.exoplatform.services.organization.impl.GroupImpl&lt;/value&gt;
          &lt;value&gt;org.exoplatform.services.organization.impl.MembershipTypeImpl&lt;/value&gt;
        &lt;/values-param&gt;
      &lt;/init-params&gt;
    &lt;/component-plugin&gt;
  &lt;/external-component-plugins&gt;  
&lt;/configuration&gt;</programlisting>
  </section>

  <section>
    <title>Disable/Enable an User</title>

    <para>To be able to disable or enable an user account which is supported
    since JCR 1.16, you have no need to change your old configuration as it is
    exactly the same configuration. Hibernate will detect automatically that
    the structure of the user table has changed and will migrate it at
    startup.</para>

    <para>If you use DB2, you can get an error of type <emphasis>SQLCODE=-668,
    SQLSTATE=57016, SQLERRMC=7</emphasis> when hibernate will try to migrate
    the table structure, to workaround this issue you only need to call the
    command <emphasis>reorg table exo_user</emphasis> </para>
  </section>
</section>
