Chapter 2. Setup and configuration

2.1. Setup

The JPA 2.0 compatible Hibernate EntityManager is built on top of
the core of Hibernate and Hibernate Annotations. Starting from version
3.5, we have bundled in a single Hibernate distribution all the necessary
modules:

What is hibernate-jpa-2.0-api-x.y.z.jar?

This is the JAR containing the JPA 2.0 API, it provides all the
interfaces and concrete classes that the specification defines as public
API. Said otherwise, you can use this JAR to bootstrap any JPA provider
implementation. Note that you typically don't need it when you deploy
your application in a Java EE 6 application server (like JBoss AS 6 for
example).

All the required dependencies like hibernate-core and
hibernate-annotations will be dragged transitively.

We recommend you use Hibernate Validator and the
Bean Validation specification capabilities as its integration with Java
Persistence 2 has been standardized. Download Hibernate Validator 4 or
above from the Hibernate website and add
hibernate-validator.jar and
validation-api.jar in your classpath. Alternatively
add the following dependency in your pom.xml.

If you wish to use Hibernate Search (full-text
search for Hibernate aplications), download it from the Hibernate website
and add hibernate-search.jar and its dependencies in
your classpath. Alternatively add the following dependency in your
pom.xml.

2.2. Configuration and bootstrapping

2.2.1. Packaging

The configuration for entity managers both inside an application
server and in a standalone application reside in a persistence archive.
A persistence archive is a JAR file which must define a
persistence.xml file that resides in the
META-INF folder. All properly annotated classes
included in the archive (ie. having an @Entity
annotation), all annotated packages and all Hibernate hbm.xml files
included in the archive will be added to the persistence unit
configuration, so by default, your persistence.xml will be quite
minimalist:

(attribute) Transaction type used. Either JTA or
RESOURCE_LOCAL (default to JTA in a JavaEE environment and to
RESOURCE_LOCAL in a JavaSE environment). When a jta-datasource is
used, the default is JTA, if non-jta-datasource is used,
RESOURCE_LOCAL is used.

provider

The provider is a fully-qualified class name of the EJB
Persistence provider. You do not have to define it if you don't
work with several EJB3 implementations. This is needed when you
are using multiple vendor implementations of EJB
Persistence.

jta-data-source,
non-jta-data-source

This is the JNDI name of where the javax.sql.DataSource is
located. When running without a JNDI available Datasource, you
must specify JDBC connections with Hibernate specific properties
(see below).

mapping-file

The class element specifies a EJB3 compliant XML mapping
file that you will map. The file has to be in the classpath. As
per the EJB3 specification, Hibernate EntityManager will try to
load the mapping file located in the jar file at
META_INF/orm.xml. Of course any explicit
mapping file will be loaded too. As a matter of fact, you can
provides any XML file in the mapping file element ie. either hbm
files or EJB3 deployment descriptor.

jar-file

The jar-file elements specifies a jar to analyse. All
properly annotated classes, annotated packages and all hbm.xml
files part of this jar file will be added to the persistence unit
configuration. This element is mainly used in Java EE environment.
Use of this one in Java SE should be considered as non portable,
in this case a absolute url is needed. You can alternatively point
to a directory (This is especially useful when in your test
environment, the persistence.xml file is not under the same root
directory or jar than your domain model).

<jar-file>file:/home/turin/work/local/lab8/build/classes</jar-file>

exclude-unlisted-classes

Do not check the main jar file for annotated classes. Only
explicit classes will be part of the persistence unit.

class

The class element specifies a fully qualified class name
that you will map. By default all properly annotated classes and
all hbm.xml files found inside the archive are added to the
persistence unit configuration. You can add some external entity
through the class element though. As an extension to the
specification, you can add a package name in the
<class> element (eg
<class>org.hibernate.eg</class>).
Caution, the package will include the metadata defined at the
package level (ie in package-info.java), it
will not include all the classes of a given package.

shared-cache-mode

By default, entities are elected for second-level cache if
annotated with @Cacheable. You can
however:

ALL: force caching for all
entities

NONE: disable caching for all
entities (useful to take second-level cache out of the
equation)

By default, Bean Validation (and Hibernate Validator) is
activated. When an entity is created, updated (and optionally
deleted), it is validated before being sent to the database. The
database schema generated by Hibernate also reflects the
constraints declared on the entity.

You can fine-tune that if needed:

AUTO: if Bean Validation is present
in the classpath, CALLBACK and DDL are activated.

CALLBACK: entities are validated on
creation, update and deletion. If no Bean Validation provider
is present, an exception is raised at initialization
time.

DDL: (not standard, see below)
database schemas are entities are validated on creation,
update and deletion. If no Bean Validation provider is
present, an exception is raised at initialization time.

NONE: Bean Validation is not used at
all

Unfortunately, DDL is not standard mode
(though extremely useful) and you will not be able to put it in
<validation-mode>. To use it, add a
regular property

The properties element is used to specify vendor specific
properties. This is where you will define your Hibernate specific
configurations. This is also where you will have to specify JDBC
connection information as well.

Here is a list of JPA 2 standard properties. Be sure to also
Hibernate Core's documentation to see Hibernate specific
properties.

javax.persistence.lock.timeout
pessimistic lock timeout in milliseconds
(Integer or
String), this is a hint used by
Hibernate but requires support by your underlying
database.

javax.persistence.query.timeout query
timeout in milliseconds (Integer or
String), this is a hint used by
Hibernate but requires support by your underlying database
(TODO is that 100% true or do we use some other
tricks).

javax.persistence.validation.mode
corresponds to the validation-mode element.
Use it if you wish to use the non standard
DDL value.

javax.persistence.validation.group.pre-persist
defines the group or list of groups to validate before
persisting an entity. This is a comma separated fully
qualified class name string (eg
com.acme.groups.Common or
com.acme.groups.Common,
javax.validation.groups.Default). Defaults to the Bean
Validation default group.

javax.persistence.validation.group.pre-update
defines the group or list of groups to validate before
updating an entity. This is a comma separated fully qualified
class name string (eg com.acme.groups.Common or
com.acme.groups.Common,
javax.validation.groups.Default). Defaults to the Bean
Validation default group.

javax.persistence.validation.group.pre-remove
defines the group or list of groups to validate before
persisting an entity. This is a comma separated fully
qualified class name string (eg
com.acme.groups.Common or
com.acme.groups.Common,
javax.validation.groups.Default). Defaults to no
group.

Note

To know more about Bean Validation and Hibernate
Validator, check out Hibernate Validator's reference
documentation as well as Hibernate Annotations's documentation
on Bean Validation.

The following properties can only be used in a SE
environment where no datasource/JNDI is available:

javax.persistence.jdbc.driver: the
fully qualified class name of the driver class

javax.persistence.jdbc.url: the
driver specific URL

javax.persistence.jdbc.user the user
name used for the database connection

javax.persistence.jdbc.password the
password used for the database connection

Be sure to define the grammar definition in the
persistence element since the JPA specification
requires schema validation. If the systemId ends with
persistence_2_0.xsd, Hibernate entityManager will use
the version embedded in the hibernate-entitymanager.jar. It won't fetch
the resource from the internet.

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.
All the properties defined in Section 2.2.1, “Packaging” can be passed to the
createEntityManagerFactory method and there are
a few additional ones:

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. 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.

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)

You can customize this scanning strategy by
implementing
org.hibernate.ejb.packaging.Scanner. This
property is used by container implementors to improve
integration with Hibernate.

Accepts an instance of
Scanner or the file name of a no-arg
constructor class implementing
Scanner.

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.

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.

2.3. Event listeners

Hibernate Entity Manager needs to enhance Hibernate core to
implements all the JPA semantics. It does that through the event listener
system of Hibernate. Be careful when you use the event system yourself,
you might override some of the JPA semantics. A safe way is to add your
event listeners to the list given below.

Table 2.2. Hibernate Entity Manager default event listeners

Event

Listeners

flush

org.hibernate.ejb.event.EJB3FlushEventListener

auto-flush

org.hibernate.ejb.event.EJB3AutoFlushEventListener

delete

org.hibernate.ejb.event.EJB3DeleteEventListener

flush-entity

org.hibernate.ejb.event.EJB3FlushEntityEventListener

merge

org.hibernate.ejb.event.EJB3MergeEventListener

create

org.hibernate.ejb.event.EJB3PersistEventListener

create-onflush

org.hibernate.ejb.event.EJB3PersistOnFlushEventListener

save

org.hibernate.ejb.event.EJB3SaveEventListener

save-update

org.hibernate.ejb.event.EJB3SaveOrUpdateEventListener

pre-insert

org.hibernate.secure.JACCPreInsertEventListener

pre-insert

org.hibernate.secure.JACCPreUpdateEventListener

pre-delete

org.hibernate.secure.JACCPreDeleteEventListener

pre-load

org.hibernate.secure.JACCPreLoadEventListener

post-delete

org.hibernate.ejb.event.EJB3PostDeleteEventListener

post-insert

org.hibernate.ejb.event.EJB3PostInsertEventListener

post-load

org.hibernate.ejb.event.EJB3PostLoadEventListener

post-update

org.hibernate.ejb.event.EJB3PostUpdateEventListener

Note that the JACC*EventListeners are removed
if the security is not enabled.

You can configure the event listeners either through the properties
(see Configuration and bootstrapping) or through the
ejb3configuration.getEventListeners() API.

2.4. Obtaining an EntityManager in a Java SE environment

An entity manager factory should be considered as an immutable
configuration holder, it is defined to point to a single datasource and to
map a defined set of entities. This is the entry point to create and
manage EntityManagers. The
Persistence class is bootstrap class to create an
entity manager factory.

An entity manager factory is typically create at application
initialization time and closed at application end. It's creation is an
expensive process. For those who are familiar with Hibernate, an entity
manager factory is very much like a session factory. Actually, an entity
manager factory is a wrapper on top of a session factory. Calls to the
entityManagerFactory are thread safe.

Thanks to the EntityManagerFactory, you can
retrieve an extended entity manager. The extended entity manager keep the
same persistence context for the lifetime of the entity manager: in other
words, the entities are still managed between two transactions (unless you
call entityManager.clear() in between). You can
see an entity manager as a small wrapper on top of an Hibernate
session.

TODO explains emf.createEntityManager(Map)

2.5. Various

Hibernate Entity Manager comes with Hibernate Validator configured
out of the box. You don't have to override any event yourself. If you do
not use Hibernate Validator annotations in your domain model, there will
be no performance cost. For more information on Hibernate Validator,
please refer to the Hibernate Annotations reference guide.