2.2.2. Bootstrapping

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:

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. Each provider, from this list of resources, it will try to find an entity manager that matches the name you specify in the command line with what is specified in the persistence.xml file (of course the provider element must match the current persistent provider). If no persistence.xml with the correct name are 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.

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. This interceptor has to implement org.hibernate.Interceptor and have a no-arg constructor.
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 sy,chronized with the database (default to false, ie wait the transaction completion)

Table 2.1. Hibernate Entity Manager specific properties


Note that you can mix XML <class> declaration and hibernate.ejb.cfgfile usage in the same configuration. Be aware of the potential clashed. 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.

TODO: me more descriptive on some APIs like setDatasource()

Ejb3Configuration cfg = new Ejb3Configuration();
EntityManagerFactory emf = 
  cfg.configure("/mypath/hibernate.cfg.xml") //add a regular hibernate.cfg.xml
     .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
     .addRerousce( "mypath/MyOtherCLass.hbm.xml ) //add an hbm.xml file
     .addRerousce( "mypath/orm.xml ) //add an EJB3 deployment descriptor
     .buildEntityManagerFactory(); //Create the entity manager factory