Version 4

    As of version 3.2.6{FOOTNOTE DEF 1 1}, JBoss comes with built-in support for utilizing Hibernate within application code. This support is provided by 3 high-level components:

    1. Hibernate MBean - provides deployment, lifecycle, and management support around a Hibernate SessionFactory;

    2. HAR Deployer - defines a Hibernate ARchive as a new deployable unit within JBoss AS;

    3. Session Management - provides transparent management of Hibernate sessions.




    Hibernate MBean

    The Hibernate MBean is responsible for constructing a Hibernate SessionFactory and exposing it through JNDI. It also provides JMX management capabilities around the deployed SessionFactory such that its configuration can be configured at runtime.





    It exposes a number of configuration properties which affect its runtime behaviour. The more important of these include:

    • DatasourceName - the JNDI name of the datasource Hibernate should use;

    • Dialect - the RDBMS dialect;

    • SessionFactoryName - the JNDI name where the constructed SessionFactory should be bound;

    • CacheProviderClass - the Hibernate CacheProvider class to use for its second-level cache.

    Check out the javadocs for org.jboss.hibernate.jmx.Hibernate for a complete list of the available configuration properties.





    Notice that there is no option to specify the mapping documents to load. That is because the Hibernate MBean is meant to work in conjuction with the HAR Deployer component and gets this information from there.





    As an example of configuring the MBean, here is the configuration used in the unit tests:

    <mbean code="org.jboss.hibernate.jmx.Hibernate" name="jboss.har:service=Hibernate">
    <attribute name="DatasourceName">java:/DefaultDS</attribute>
    <attribute name="SessionFactoryName">java:/hibernate/SessionFactory</attribute>
    <attribute name="Dialect">net.sf.hibernate.dialect.HSQLDialect</attribute>
    <attribute name="CacheProviderClass">net.sf.hibernate.cache.HashtableCacheProvider</attribute>
    <attribute name="Hbm2ddlAuto">create-drop</attribute>

    Note especially the MBean name and the SessionFactoryName attribute; we'll see them again shortly!


    HAR Deployer

    A Hibernate ARchive (or HAR) includes all the resources needed to deploy one or more Hibernate MBean instances. The archive must end in a .har extension and contain a meta-inf/hibernate-service.xml which defines the Hibernate MBean(s) to deploy as well all the domain classes and their mappings. The mappings can occur anywhere in the archive; the classes should maintain package structure. When a HAR is processed by the HAR Deployer, a Hibernate MBean instance is created based on the HAR's meta-inf/hibernate-service.xml and the contents of the har (the mappings are processed using Hibernate's Configuration.addJar() method).





    A HAR can be deployed stand-alone or as part of an EAR. If included in an EAR, the EAR's meta-inf/jboss-app.xml must define the har as a module as such:

    module type used to denote the HAR subdeployment.





    The HAR deployer is defined in the hibernate-deployer-service.xml file which by default is included in both the all and default configuration sets. It defines a single configuration property named "ValidateDTDs", which denotes whether DTDs should be validated on deployment.


    Session Management

    There are two perspectives to the session management commponent.





    First is the applications view. An application need only deal with the org.jboss.hibernate.session.SesssionContext class, and specifically its getSession() method. SessionContext.getSession() takes a string representing the jndi name of a SessionFactory and returns the Session, obtained from that SessionFactory, bound to the current context. That's all there is to it. No need to explicitly open or close the Session.





    The second perspective deals with how a Session is bound to the current context. That is handled by interceptors. Interceptors currently come in the form of either an EJB interceptor (org.jboss.hibernate.session.EjbInterceptor) or a web filter (org.jboss.hibernate.session.FilterInterceptor). Currently both assume SessionFactory deployment as an MBean. Each of the interceptors take two parameters:

    • service - the ObjectName reference to the Hibernate MBean

    • scope - should the managed session be scoped by "thread" or by "transaction". Transaction scoping has a few caveats (because of which "thread" is the default):

      1. Keep in mind that this is an interceptor setting; meaning that all use-cases affected by the given interceptor should be governed by a JTA transaction.

      2. The JTA transaction must be started prior to binding the Session; for EJBs, the practical implication is that only CMT can be used; for web filter, probably means a seperate web filter managing a transaction should be applied prior to the session web filter in the filter chain.





    As an example, here is the <container-configuration/> element used in the unit tests:

    <container-configuration extends="Standard Stateless SessionBean">
    <container-name>Hibernate Stateless SessionBean</container-name>
    <!-- CMT -->
    <interceptor transaction="Container">org.jboss.ejb.plugins.TxInterceptorCMT</interceptor>
    <interceptor transaction="Container" metricsEnabled="true">org.jboss.ejb.plugins.MetricsInterceptor</interceptor>
    <interceptor transaction="Container">org.jboss.ejb.plugins.StatelessSessionInstanceInterceptor</interceptor>
    <!-- BMT not feasible using Hibernate interceptor with 'transaction' scope!!!! -->
    <!-- Notice that the service name is the same as that used to define the MBean -->
    <interceptor service="jboss.har:service=Hibernate" scope="transaction">org.jboss.hibernate.session.EjbInterceptor</interceptor>

    Then any session bean using this configuration (and even any code called from that session bean!) can simply obtain the current session for the context by calling:

    // Notice that the parameter pssed here to the getSession() method is the
    // same as that configured on the MBean in the hibernate-service.xml!
    Session session = org.jboss.hibernate.session.SessionContext.getSession("java:/hibernate/SessionFactory");



    Note that there are two approaches to getting a session bean to "use this configuration"; the first is to simply replace the standard container configuration definition in standardjboss.xml; the other is to define the container in the ejb's jboss.xml, and to apply the <configuration-name/> element to the ejbs which should use this configuration.  Consult the JBoss documentation for further information.

    Similarly, this can be applied to web apps by defining a filter:

    <filter-name>Hibernate Session Filter</filter-name>






    Why the need to pass the JNDI name to the SessionContext.getSession() method? The SessionContext class supports multiple simultaneously deployed SessionFactories. You need to specify from which of those deployed SessionFactories you want the current session.






    {FOOTNOTE RED #1 1} 3.2.6RC1 is missing the hibernate-deployer-service.xml from the deploy directories. It also contains a version of the jboss-hibernate.jar archive that was "cut" prior to the working version. To use this support in 3.2.6RC1, perform the following two steps:

    • download the attached hibernate-deployer-service.xml file and place it into your appropriate deploy directory;

    • download the attached jboss-hibernate.jar file and place it into your appropriate lib directory (this could either be the root lib directory, or the server-config-specific lib directory).