Red Hat Training

A Red Hat training course is available for JBoss Enterprise Application Platform Common Criteria Certification

2.2.2. Bootstrapping

The EJB3 specification defines a bootstrap procedure to access the EntityManagerFactory and the EntityManager. The bootstrap class is javax.persistence.Persistence, e.g.
EntityManagerFactory emf = Persistence.createEntityManagerFactory("manager1");
//or
Map configOverrides = new HashMap();
configOverrides.put("hibernate.hbm2ddl.auto", "create-drop");
EntityManagerFactory programmaticEmf =
    Persistence.createEntityManagerFactory("manager1", configOverrides);
The first version is equivalent to the second with an empty map. The map version is a set of overrides that will take precedence over any properties defined in your persistence.xml files. There are a couple of EJB3 properties usable in the map:
  • javax.persistence.provider to define the provider class used
  • javax.persistence.transactionType to define the transaction type used (either JTA or RESOURCE_LOCAL)
  • javax.persistence.jtaDataSource to define the JTA datasource name in JNDI
  • javax.persistence.nonJtaDataSource to define the non JTA datasource name in JNDI
When Persistence.createEntityManagerFactory() is called, the persistence implementation will search your classpath for any META-INF/persistence.xml files using the ClassLoader.getResource("META-INF/persistence.xml") method. Actually the Persistence class will look at all the Persistence Providers available in the classpath and ask each of them if they are responsible for the creation of the entity manager factory manager1. From the list of resources available from each provider, the persistence implementation will search for an entity manager that whose name in persistence.xml matches the name specified at the command line. (The provider element must match the current persistence provider.) If no persistence.xml with the correct name is found or if the expected persistence provider is not found, a PersistenceException is raised.
Apart from Hibernate system-level settings, all the properties available in Hibernate can be set in properties element of the persistence.xml file or as an override in the map you pass to createEntityManagerFactory(). Please refer to the Hibernate reference documentation for a complete listing. There are however a couple of properties available in the EJB3 provider only.

Table 2.1. Hibernate Entity Manager specific properties

Property name Description
hibernate.ejb.classcache. <classname> class cache strategy [comma cache region] of the class Default to no cache, and default region cache to fully.qualified.classname (eg. hibernate.ejb.classcache.com.acme.Cat read-write or hibernate.ejb.classcache.com.acme.Cat read-write, MyRegion).
hibernate.ejb.collectioncache. <collectionrole> collection cache strategy [comma cache region] of the class Default to no cache, and default region cache to fully.qualified.classname.role (eg. hibernate.ejb.classcache.com.acme.Cat read-write or hibernate.ejb.classcache.com.acme.Cat read-write, MyRegion).
hibernate.ejb.cfgfile XML configuration file to use to configure Hibernate (eg. /hibernate.cfg.xml).
hibernate.archive. autodetection Determine which element is auto discovered by Hibernate Entity Manager while parsing the .par archive. (default to class,hbm).
hibernate.ejb. interceptor An optional Hibernate interceptor. The interceptor instance is shared by all Session instances. This interceptor has to implement org.hibernate.Interceptor and have a no-arg constructor. This property can not be combined with hibernate.ejb.interceptor.session_scoped.
hibernate.ejb.interceptor. session_scoped An optional Hibernate interceptor. The interceptor instance is specific to a given Session instance (and hence can be non thread-safe). This interceptor has to implement org.hibernate.Interceptor and have a no-arg constructor. This property can not be combined with hibernate.ejb.interceptor.
hibernate.ejb.naming_strategy An optional naming strategy. The default naming strategy used is EJB3NamingStrategy. You also might want to consider the DefaultComponentSafeNamingStrategy.
hibernate.ejb.event. <eventtype> Event listener list for a given eventtype. The list of event listeners is a comma separated fully qualified class name list (eg. hibernate.ejb.event.pre-load com.acme.SecurityListener, com.acme.AuditListener)
hibernate.ejb. use_class_enhancer Whether or not use Application server class enhancement at deployment time (default to false)
hibernate.ejb. discard_pc_on_close If true, the persistence context will be discarded (think clear() when the method is called. Otherwise the persistence context will stay alive till the transaction completion: all objects will remain managed, and any change will be synchronized with the database (default to false, ie wait the transaction completion)
Note that you can mix XML <class> declaration and hibernate.ejb.cfgfile usage in the same configuration. Be aware of the potential clashes. The properties set in persistence.xml will override the one in the defined hibernate.cfg.xml.

Note

It is important that you do not override hibernate.transaction.factory_class, Hibernate EntityManager automatically set the appropriate transaction factory depending on the EntityManager type (ie JTA versus RESOURSE_LOCAL). If you are working in a Java EE environment, you might want to set the hibernate.transaction.manager_lookup_class though.
Here is a typical configuration in a J2SE environment
<persistence>
   <persistence-unit name="manager1" transaction-type="RESOURCE_LOCAL">
      <class>org.hibernate.ejb.test.Cat</class>
      <class>org.hibernate.ejb.test.Distributor</class>
      <class>org.hibernate.ejb.test.Item</class>
      <properties>
         <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
         <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
         <property name="hibernate.connection.username" value="sa"/>
         <property name="hibernate.connection.password" value=""/>
         <property name="hibernate.connection.url" value="jdbc:hsqldb:."/>
         <property name="hibernate.max_fetch_depth" value="3"/>
       
         <!-- cache configuration -->
         <property name="hibernate.ejb.classcache.org.hibernate.ejb.test.Item" value="read-write"/>
         <property name="hibernate.ejb.collectioncache.org.hibernate.ejb.test.Item.distributors" value="read-write, RegionName"/>

         <!-- alternatively to <class> and <property> declarations, you can use a regular hibernate.cfg.xml file -->
         <!-- property name="hibernate.ejb.cfgfile" value="/org/hibernate/ejb/test/hibernate.cfg.xml"/ -->
      </properties>
   </persistence-unit>
</persistence>
To ease the programmatic configuration, Hibernate Entity Manager provide a proprietary API. This API is very similar to the Configuration API and share the same concepts: Ejb3Configuration. Refer to the JavaDoc and the Hibernate reference guide for more detailed informations on how to use it.
Ejb3Configuration cfg = new Ejb3Configuration();
EntityManagerFactory emf = 
  cfg.addProperties( properties ) //add some properties
     .setInterceptor( myInterceptorImpl ) // set an interceptor
     .addAnnotatedClass( MyAnnotatedClass.class ) //add a class to be mapped
     .addClass( NonAnnotatedClass.class ) //add an hbm.xml file using the Hibernate convention
     .addResource( "mypath/MyOtherCLass.hbm.xml" ) //add an hbm.xml file
     .addResource( "mypath/orm.xml" ) //add an EJB3 deployment descriptor
     .configure("/mypath/hibernate.cfg.xml") //add a regular hibernate.cfg.xml
     .buildEntityManagerFactory(); //Create the entity manager factory