A beginner’s guide to JPA persistence.xml file
Imagine having a tool that can automatically detect JPA and Hibernate performance issues. Wouldn’t that be just awesome?
Well, Hypersistence Optimizer is that tool! And it works with Spring Boot, Spring Framework, Jakarta EE, Java EE, Quarkus, or Play Framework.
So, enjoy spending your time on the things you love rather than fixing performance issues in your production system on a Saturday night!
In this article, I’m going to explain what is the purpose of the JPA
persistence.xml configuration file, and how you can set up a Java Persistence application using the available XML tags or attributes.
While Spring applications can bootstrap without needing an XML JPA configuration file, it’s still important to understand the meaning of each configuration option since Spring also offers an alternative way when building a Java Persistence
LocalContainerEntityManagerFactoryBean or the Hibernate-specific
persistence.xml configuration file is used to configure a given JPA Persistence Unit. The Persistence Unit defines all the metadata required to bootstrap an
EntityManagerFactory, like entity mappings, data source, and transaction settings, as well as JPA provider configuration properties.
The goal of the
EntityManagerFactory is used to create
EntityManager objects we can for entity state transitions.
persistence.xml configuration file defines all the metadata we need in order to bootstrap a JPA
JPA persistence XML file location
persistence.xml is located in a
META-INF folder that needs to reside in the root of the Java classpath. If you’re using Maven, you can store it in the
resources folder, like this:
JPA persistence XML file structure
persistence.xml configuration file is structured as follows:
<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.2" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"> <persistence-unit name="HypersistenceOptimizer" transaction-type="JTA"> <description> Hypersistence Optimizer is a dynamic analyzing tool that can scan your JPA and Hibernate application and provide you tips about the changes you need to make to entity mappings, configurations, queries, and Persistence Context actions to speed up your data access layer. </description> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <jta-data-source>java:global/jdbc/default</jta-data-source> <properties> <property name="hibernate.transaction.jta.platform" value="SunOne" /> </properties> </persistence-unit> </persistence>
persistence tag is the root XML element, and it defines the JPA version and the XML schema used to validate the
persistence.xml configuration file.
persistence-unit element defines the name of the associated JPA Persistence Unit, which you can later use to reference it when using the
@PersistenceUnit JPA annotation to inject the associated
@PersistenceUnit(name = "HypersistenceOptimizer") private EntityManagerFactory entityManagerFactory;
transaction-type attribute defines the JPA transaction strategy, and it can take one of the following two values:
Traditionally, Java EE applications used JTA by default, which requires having a JTA transaction manager that uses the 2PC (Two-Phase Commit) protocol to apply changes atomically to multiple sources of data (e.g., database systems, JMS queues, Caches).
If you want to propagate changes to a single data source, then you don’t need JTA, so the
RESOURCE_LOCAL transaction type is a much more efficient alternative. For instance, by default, Spring applications use
RESOURCE_LOCAL transactions, and to use
JTA, you need to explicitly choose the
JtaTransactionManager Spring bean.
description element allows you to provide more details about the goals of the current Persistence Unit.
provider XML element defines the fully-qualified class name implementing the JPA
If you are using Hibernate 4.3 or newer versions, then you need to use the
If you are using Hibernate 4.2 or older versions, then you need to use the
org.hibernate.ejb.HibernatePersistenceclass name instead.
jta-data-source and non-jta-data-source
It’s very unusual that the JPA spec defines two different XML tags to provide the JNDI
DataSource name. There should have been a single
data-source attribute for that since the
transaction-type already specifies whether JTA is used or not.
No, if you’re using JTA, you can use the
jta-data-source to specify the JNDI name for the associated JTA
DataSource, while for
RESOURCE_LOCAL, you need to use the
If you’re using Hibernate, you can also use the
hibernate.connection.datasourceconfiguration property to specify the JDBC
DataSourceto be used.
properties element allows you to define JPA or JPA provider-specific properties to configure:
- the Hibernate
- the JTA transaction platform (e.g., GlassFish, JBoss, Bitronix, Atomikos)
- whether the database schema should be auto-generated
- whether Hibernate should skip the auto-commit check for RESOURCE_LOCAL transactions
- activate the slow SQL query log
- and many more properties you can find in the
Entity mapping settings
By default, Hibernate is capable of finding the JPA entity classes based on the presence of the
@Entity annotation, so you don’t need to declare the entity classes.
However, if you want to explicitly set the entity classes to be be used, and exclude any other entity classes found on the current Java classpath, then you need to set the
exclude-unlisted-classes element to the value of
After setting the
exclude-unlisted-classes XML element above, you need to specify the list of entity classes registered by the current Persistence Unit via the
class XML element:
<class>io.hypersistence.optimizer.forum.domain.Post</class> <class>io.hypersistence.optimizer.forum.domain.PostComment</class> <class>io.hypersistence.optimizer.forum.domain.PostDetails</class> <class>io.hypersistence.optimizer.forum.domain.Tag</class>
The vast majority of JPA and Hibernate applications use annotations to build the object-relational mapping metadata. However, even if you are using annotations, you can still use XML mappings to override the static annotation metadata with the one provided via an
orm.xml configuration file.
For instance, you can use the
SEQUENCEidentifier generator by default using the
@SequenceGeneratorannotation and substitute that with
IDENTITYfor MySQL, which does not support database sequences.
For more details about this topic, check out this article.
By default, the
orm.xml configuration file is located in the
META-INF folder. If you want to use a different file location, you can use the
mapping-file XML element in the
persistence.xml file, like this:
For more details about using external
orm.xmlfiles to provide JPA mappings in XML format, check out this article.
Bu default, the JPA provider is going to scan the current Java classpath to load entity classes or XML mappings. If you want to provide one or more JAR files to be scanned, you can use the
jar-file element, like this:
shared-cache-mode element allows you to define the
SharedCacheMode strategy for storing entities in the second-level cache, and it can take one of the following values:
ALL– stores all entities in the second-level cache,
NONE– entities are not stored in the second-level cache,
ENABLE_SELECTIVE– no entity is cached by default, except for the ones marked with the
@Cacheable(true)annotation, which are going to be cached
DISABLE_SELECTIVE– all entities are cached by default, except for the ones marked with the
UNSPECIFIED– uses the JPA provider default caching strategy. This is also the default value that’s used when the
shared-cache-modeelement is not set.
You can also override the
shared-cache-mode strategy programmatically using the
javax.persistence.cache.storeMode property, like this:
EntityManagerFactory entityManagerFactory = Persistence .createEntityManagerFactory( "HypersistenceOptimizer", Collections.singletonMap( "javax.persistence.cache.storeMode", SharedCacheMode.ENABLE_SELECTIVE ) );
validation-mode XML element specifies the
ValidationMode strategy, which instructs the JPA provider whether it should check the entities Bean Validation at runtime.
validation-mode element can take the following values:
AUTO– If a Bean Validation provider is found in the current Java classpath, it will be registered automatically, and all entities are going to be validated. If no Bean Validation provider is found, entities are not validated. This is the default value.
CALLBACK– Entities must always be validated by a Bean Validation provider. If the JPA provider does no found a Bean Validation implementation on the classpath, the bootstrap process will fail.
NONE– Entities are not validated even if a Bean Validation provider is found on the classpath.
You can also override the
validation-mode strategy programmatically using the
javax.persistence.validation.mode property, like this:
EntityManagerFactory entityManagerFactory = Persistence .createEntityManagerFactory( "HypersistenceOptimizer", Collections.singletonMap( "javax.persistence.validation.mode", ValidationMode.CALLBACK ) );
The Java Persistence XML configuration file allows you to define a Persistence Unit configuration that you can later bootstrap using Java EE or Spring.
Knowing all the
persistence.xml file configuration options is very important as it allows you to address a great variety of mapping requirements.