在本文中,我们会解释 JPA persistence.xml
配置文件的用途,以及如何使用可用的 XML 标记或属性设置 Java Persistence 应用程序。
虽然 Spring 应用程序可以在不需要 XML JPA 配置文件的情况下进行引导,但理解每个配置选项的含义仍然很重要,因为 Spring 在构建 Java Persistence
LocalContainerEntityManagerFactoryBean
或 Hibernate-specific LocalSessionFactoryBean
时还提供了另一种方法。
Persistence Unit
persistence.xml 配置文件用于配置给定的 JPA 持久化单元。持久化单元定义了引导 EntityManagerFactory
所需的所有元数据,例如实体映射、数据源和事务设置,以及 JPA proviser配置属性。
EntityManagerFactory
的目标是创建我们可以用于实体状态转换的 EntityManager
对象。
因此,persistence.xml
配置文件定义了引导 JPA EntityManagerFactory
所需的所有元数据。
JPA 持久化 XML 文件位置
传统上,persistence.xml
位于一个 META-INF 文件夹中,该文件夹需要驻留在 Java 类路径的根目录中。如果您使用的是 Maven,则可以将其存储在资源文件夹中,如下所示:
src/main/resources/META-INF/persistence.xml
JPA 持久性 XML 文件结构
persistence.xml
配置文件结构如下:
<?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>是根 XML 元素,它定义了 JPA 版本2.2和用于验证 persistence.xml
配置文件的 XML 模式。
持久化单元
<persistence-unit> 元素定义了关联的 JPA Persistence Unit 的名称,稍后您可以在使用 @PersistenceUnit
JPA 注解注入关联的 EntityManagerFactory
实例时使用它来引用它:
@PersistenceUnit(name = "HypersistenceOptimizer")
private EntityManagerFactory entityManagerFactory;
transaction-type
属性定义了 JPA 事务策略,它可以取以下两个值之一:
- JTA
- RESOURCE_LOCAL
传统上,Java EE 应用程序默认使用 JTA,这需要有一个使用 2PC(两阶段提交)协议的 JTA 事务管理器以原子方式将更改应用于多个数据源(例如,数据库系统、JMS 队列、缓存)。
如果要将数据更改传播到单个数据源,则不需要 JTA,因此 RESOURCE_LOCAL 事务类型是一种更有效的替代方案。例如,默认情况下,Spring 应用程序使用 RESOURCE_LOCAL 事务,而要使用 JTA,您需要显式选择 JtaTransactionManager Spring bean。
简单总结一:如果涉及到多个数据源,则使用JTA,否则使用RESOURCE_LOCAL 。
描述
<description>元素允许您提供有关当前持久化单元目标的更多详细信息。
provider
<provider> XML 元素定义了实现 JPA PersistenceProvider 接口的完全限定类名。
如果您使用的是 Hibernate 4.3 或更新版本,那么您需要使用 org.hibernate.jpa.HibernatePersistenceProvider 类名。
如果您使用的是 Hibernate 4.2 或更早版本,则需要使用 org.hibernate.ejb.HibernatePersistence 类名。
jta 数据源和非 jta 数据源
JPA 规范定义两个不同的 XML 标记来提供 JNDI 数据源名称是非常不寻常的。应该有一个单独的数据源属性,因为事务类型已经指定是否使用 JTA。
不,如果您使用 JTA,您可以使用 jta-data-source 为关联的 JTA DataSource 指定 JNDI 名称,而对于 RESOURCE_LOCAL,您需要使用 non-jta-data-source。
如果您使用的是 Hibernate,还可以使用 hibernate.connection.datasource 配置属性来指定要使用的 JDBC 数据源。
properties
properties 元素允许您定义要配置的 JPA 或 JPA 提供程序特定的属性:
- the Hibernate
Dialect
- the JTA transaction platform (e.g., GlassFish, JBoss, Bitronix, Atomikos)
- 是否应该自动生成数据库模式
- Hibernate 是否应该跳过对 RESOURCE_LOCAL 事务的自动提交检查
- 激活慢SQL查询日志
- 您可以在 org.hibernate.cfg.AvailableSettings 界面中找到更多属性。
举个例子:
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
<!-- H2 is running in pure in Memory db mode, data1.txt will be lost as soon as connection is closed -->
<property name="hibernate.connection.url" value="jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE"/>
<property name="hibernate.connection.username" value="sa"/>
<property name="hibernate.connection.pool_size" value="5"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="org.hibernate.type.descriptor.sql.BasicBinder" value="true"/>
<property name="org.hibernate.type.descriptor.sql.BasicExtractor" value="true"/>
</properties>
实体映射设置
默认情况下,Hibernate 能够根据 @Entity 注解的存在来查找 JPA 实体类,因此您无需声明实体类。
exclude-unlisted-classes
但是,如果要显式设置要使用的实体类,并排除在当前 Java 类路径中找到的任何其他实体类,则需要将 exclude-unlisted-classes 元素设置为 true 值:
<exclude-unlisted-classes>true</exclude-unlisted-classes>
class
在上面设置了 exclude-unlisted-classes XML 元素后,需要通过 class XML 元素指定当前 Persistence Unit 注册的实体类的列表:
<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>
绝大多数 JPA 和 Hibernate 应用程序使用注释来构建对象关系映射元数据。 但是,即使您正在使用注解,您仍然可以使用 XML 映射来覆盖静态注解元数据,并使用通过 orm.xml 配置文件提供的元数据。
mapping-file
默认情况下,orm.xml 配置文件位于 META-INF 文件夹中。如果要使用不同的文件位置,可以使用 persistence.xml 文件中的 mapping-file XML 元素,如下所示:
<mapping-file>file:///D:/Vlad/Work/Examples/mappings/orm.xml</mapping-file>
jar-file
但默认情况下,JPA 提供程序将扫描当前 Java 类路径以加载实体类或 XML 映射。如果要提供一个或多个要扫描的 JAR 文件,可以使用 jar-file 元素,如下所示:
<jar-file>lib/hypersistence-optimizer-glassfish-hibernate-example.jar</jar-file>
shared-cache-mode
shared-cache-mode 元素允许您定义将实体存储在二级缓存中的 SharedCacheMode 策略,它可以采用以下值之一:
- ALL – 将所有实体存储在二级缓存中,
- NONE – 实体不存储在二级缓存中,
- ENABLE_SELECTIVE – 默认情况下不缓存任何实体,除了标记有 @Cacheable(true) 注释的实体,它们将被缓存
- DISABLE_SELECTIVE - 默认情况下所有实体都被缓存,除了标有@Cacheable(false) 注释的实体
- 未指定 - 使用 JPA 提供程序默认缓存策略。这也是未设置 shared-cache-mode 元素时使用的默认值。
您还可以使用 javax.persistence.cache.storeMode 属性以编程方式覆盖共享缓存模式策略,如下所示:
EntityManagerFactory entityManagerFactory = Persistence
.createEntityManagerFactory(
"HypersistenceOptimizer",
Collections.singletonMap(
"javax.persistence.cache.storeMode",
SharedCacheMode.ENABLE_SELECTIVE
)
);
validation-mode
验证模式 XML 元素指定 ValidationMode 策略,它指示 JPA 提供者是否应该在运行时检查实体 Bean Validation。
验证模式元素可以采用以下值:
- AUTO – 如果在当前 Java 类路径中找到 Bean Validation 提供程序,它将自动注册,并且所有实体都将被验证。 如果未找到 Bean Validation 提供程序,则不会验证实体。 这是默认值。
- CALLBACK – 实体必须始终由 Bean 验证提供程序进行验证。如果 JPA 提供者没有在类路径上找到 Bean Validation 实现,则引导过程将失败。
- NONE – 即使在类路径中找到 Bean Validation 提供程序,也不会验证实体。
您还可以使用 javax.persistence.validation.mode 属性以编程方式覆盖验证模式策略,如下所示:
EntityManagerFactory entityManagerFactory = Persistence
.createEntityManagerFactory(
"HypersistenceOptimizer",
Collections.singletonMap(
"javax.persistence.validation.mode",
ValidationMode.CALLBACK
)
);
以上属性基本上总结了持久化单元的一些基本属性,如果还有其他的属性,欢迎大家一起讨论学习。