Apache OpenJPA 3.2.2 常用工具与 API 详解

Apache OpenJPA 3.2.2 常用工具与 API 详解:官方命令行工具 PCEnhancer(构建期增强)/SchemaTool/MappingTool/ApplicationIdTool 的用法与实测 help 回显,以及 EntityManagerFactory/EntityManager/EntityTransaction/JPQL 核心 API 与代码示例、增强类验证(javap),含 FAQ,全程实测。

Apache OpenJPAApache OpenJPA2026/10/12

Apache OpenJPA 3.2.2 常用工具与 API 详解

目标:详解 Apache OpenJPA 3.2.2 的官方工具与核心 API 使用。OpenJPA 提供 4 个命令行工具(PCEnhancer、SchemaTool、MappingTool、ApplicationIdTool),通过 java -cp 调用其主类执行;编程接口以 JPA 标准 API(EntityManagerFactory/EntityManager/EntityTransaction)为主,辅以 JPQL 查询。本文给出各工具 -help 实测回显、增强器实测运行与验证(javap),以及 API 代码示例与真实回显。所有示例在 Ubuntu 22.04.5 LTS + JDK 11 + OpenJPA 3.2.2 环境实测。

一、环境信息

  • 操作系统:Ubuntu 22.04.5 LTS
  • Java:OpenJDK 11.0.32.1
  • OpenJPA 版本:3.2.2
  • 全量 jar:/opt/apache-openjpa-3.2.2/openjpa-all-3.2.2.jar(含全部依赖,直接 java -cp 使用)
  • 工程 classpath:/root/openjpa-demo/target/classes + /tmp/cp.txt(mvn dependency:build-classpath 生成)
  • 示例工程:/root/openjpa-demo/

二、工具概览

OpenJPA 工具均为 Java 主类,无独立可执行文件,统一以 java -cp <classpath> <主类> [参数] 方式调用(等价 openjpa-all-3.2.2.jar 全量包直接运行):

工具主类用途
PCEnhancerorg.apache.openjpa.enhance.PCEnhancer实体类构建期增强(生成 PersistenceCapable 实现)
SchemaToolorg.apache.openjpa.jdbc.schema.SchemaTool生成/维护数据库 schema(DDL)
MappingToolorg.apache.openjpa.jdbc.meta.MappingTool生成/校验实体-表映射与 DDL
ApplicationIdToolorg.apache.openjpa.enhance.ApplicationIdTool为复合主键实体生成主键类源码
Maven 插件openjpa-maven-plugin:enhance构建期自动增强(推荐,绑定 process-classes)

编程 API 概览:

API 类包作用
EntityManagerFactoryjavax.persistence创建 EntityManager 的工厂(对应持久化单元)
EntityManagerjavax.persistence实体增删改查、事务边界与 JPQL 执行
EntityTransactionjavax.persistence资源本地事务(RESOURCE_LOCAL)
Persistencejavax.persistence引导入口 createEntityManagerFactory("单元名")
PersistenceCapableorg.apache.openjpa.enhance增强后实体实现的内部接口

三、前置条件

export LANG=C.UTF-8 LC_ALL=C.UTF-8
cd /root/openjpa-demo
mvn -q clean process-classes
mvn -q dependency:build-classpath -Dmdep.outputFile=/tmp/cp.txt
  • 全量 jar 方式无需工程依赖,直接使用 /opt/apache-openjpa-3.2.2/openjpa-all-3.2.2.jar。

四、官方工具详解

4.1 PCEnhancer(实体增强器)

作用:把 JPA 实体类增强为 org.apache.openjpa.enhance.PersistenceCapable 实现,是 OpenJPA 运行的前置条件(生产默认禁止未增强实体)。

查看用法:

java -cp /opt/apache-openjpa-3.2.2/openjpa-all-3.2.2.jar org.apache.openjpa.enhance.PCEnhancer -help

实测回显:

Usage: java org.apache.openjpa.enhance.PCEnhancer
        [-properties/-p <properties file or resource>]
        [-<property name> <property value>]*
        [-directory/-d <output directory>]
        [-addDefaultConstructor/-adc <true/t | false/f>]
        [-jdoEnhance/-jdo <true/t | false/f>]
        [-enforcePropertyRestrictions/-epr <true/t | false/f>]
        [-tmpClassLoader/-tcl <true/t | false/f>]
        <class name | .java file | .class file | .jdo file>+

参数速查(实测 help 标注):

参数简写默认值作用
-properties-p无属性文件(可含 openjpa.* 配置)
-directory-d当前目录增强输出目录
-addDefaultConstructor-adctrue自动补无参构造器
-jdoEnhance-jdofalse同时生成 JDO 支持
-enforcePropertyRestrictions-eprtrue强制执行属性访问限制
-tmpClassLoader-tcltrue使用临时类加载器

实测运行(增强 demo/Employee.class):

cd /root/openjpa-demo
java -cp /opt/apache-openjpa-3.2.2/openjpa-all-3.2.2.jar:target/classes org.apache.openjpa.enhance.PCEnhancer demo/Employee.class

实测回显:

100  openjpa-demo  INFO   [main] openjpa.Tool - Enhancer running on type "class demo.Employee".

验证增强结果:

javap -p target/classes/demo/Employee.class | head -5

实测回显:

Compiled from "Employee.java"
public class demo.Employee implements org.apache.openjpa.enhance.PersistenceCapable {
  private long id;
  private java.lang.String name;
  private java.lang.String department;

💡 说明:增强后的类还包含 pcFieldNames/pcFieldTypes/pcStateManager/pcDetachedState 等内部字段与方法(javap -p 可见)。生产环境推荐用 openjpa-maven-plugin 在 process-classes 阶段自动增强,免手动调用。

4.2 SchemaTool(schema 维护工具)

作用:按 .schema 文件或数据库现网结构生成/维护 DDL。

java -cp /opt/apache-openjpa-3.2.2/openjpa-all-3.2.2.jar org.apache.openjpa.jdbc.schema.SchemaTool -help

实测回显:

Usage: java org.apache.openjpa.jdbc.schema.SchemaTool
        [-properties/-p <properties file or resource>]
        [-<property name> <property value>]*
        [-file/-f <stdout | output file or resource>]
        [-ignoreErrors/-i <true/t | false/f>]
        [-dropTables/-dt <true/t | false/f>]
        [-openjpaTables/-ot <true/t | false/f>]
        [-dropSequences/-dsq <true/t | false/f>]
        [-sequences/-sq <true/t | false/f>]
        [-primaryKeys/-pk <true/t | false/f>]
        [-foreignKeys/-fk <true/t | false/f>]
        [-indexes/-ix <true/t | false/f>]
        [-record/-r <true/t | false/f>]
        [-action/-a <add | retain | drop | refresh | build | reflect
                | createDB | dropDB | import | export | deleteTableContents>]
        <.schema file or resource>*

典型用法:

java -cp /opt/apache-openjpa-3.2.2/openjpa-all-3.2.2.jar \
  org.apache.openjpa.jdbc.schema.SchemaTool \
  -p /root/openjpa-demo/src/main/resources/META-INF/persistence.xml \
  -a export -f stdout
  • -action/-a:核心动作——build(按映射建表)、reflect(反查库结构)、export/import(导出/导入 .schema 文件)、drop、deleteTableContents 等。
  • -file/-f stdout:DDL 输出到标准输出(可指定输出文件)。
  • 生产 DBA 场景:-a export -f schema.sql 由开发导出 DDL,DBA 审阅后执行。

4.3 MappingTool(映射与 DDL 生成工具)

作用:生成/校验实体类到数据库表的映射,输出 DDL。

java -cp /opt/apache-openjpa-3.2.2/openjpa-all-3.2.2.jar org.apache.openjpa.jdbc.meta.MappingTool -help

实测回显:

Usage: java org.apache.openjpa.jdbc.meta.MappingTool
        [-properties/-p <properties file or resource>]
        [-<property name> <property value>]*
        [-file/-f <stdout | output file or resource>]
        [-schemaFile/-sf <stdout | output file or resource>]
        [-sqlFile/-sql <stdout | output file or resource>]
        [-sqlEncode/-se <Java character set encoding like UTF-8>]
        [-schemaAction/-sa <add | retain | drop | refresh | build | none>]
        [-schemas/-s <schemas and tables>]
        [-readSchema/-rs <true/t | false/f>]
        [-primaryKeys/-pk <true/t | false/f>]
        [-foreignKeys/-fk <true/t | false/f>]
        [-indexes/-ix <true/t | false/f>]
        [-dropTables/-dt <true/t | false/f>]
        [-openjpaTables/-ot <true/t | false/f>]
        [-dropSequences/-dsq <true/t | false/f>]
        [-sequences/-sq <true/t | false/f>]
        [-ignoreErrors/-i <true/t | false/f>]
        [-action/-a <refresh | add | buildSchema | drop | validate | import
| export>]
        <class name | .java file | .class file | .jdo file | .orm file | .mapping file>*

典型用法:

java -cp /opt/apache-openjpa-3.2.2/openjpa-all-3.2.2.jar:target/classes \
  org.apache.openjpa.jdbc.meta.MappingTool \
  -p /root/openjpa-demo/src/main/resources/META-INF/persistence.xml \
  -a buildSchema -sql stdout demo.Employee
  • -action/-a buildSchema:按实体映射直接建表(等价 persistence.xml 的 SynchronizeMappings=buildSchema,可离线独立执行);validate 校验映射与库表一致性;refresh/add/drop 维护既有结构。
  • -sql stdout:把生成的 SQL 输出到标准输出,便于审阅。

4.4 ApplicationIdTool(主键类生成工具)

作用:为使用复合主键(@IdClass/@EmbeddedId)的实体生成应用主键类源码。

java -cp /opt/apache-openjpa-3.2.2/openjpa-all-3.2.2.jar org.apache.openjpa.enhance.ApplicationIdTool -help

实测回显:

Usage: java org.apache.openjpa.enhance.ApplicationIdTool
        [-properties/-p <properties file or resource>]
        [-<property name> <property value>]*
        [-ignoreErrors/-i <true/t | false/f>]*
        [-directory/-d <output directory>]
        [-name/-n <id class name>]
        [-suffix/-s <id class suffix>]
        [-token/-t <token>]
        [-codeFormat/-cf.<property name> <property value>]*
        <class name | .java file | .class file | .jdo file>+

典型用法:

java -cp /opt/apache-openjpa-3.2.2/openjpa-all-3.2.2.jar:target/classes \
  org.apache.openjpa.enhance.ApplicationIdTool \
  -d src/main/java -n demo.EmployeeId demo.Employee
  • -directory/-d:生成的 .java 输出目录。
  • -name/-n:生成的主键类类名(默认 EmployeeId)。
  • -suffix/-s:类名后缀(默认 Id)。
  • -token/-t:拆分字段名的分隔符。

4.5 Maven 插件方式(推荐)

构建期增强推荐用 openjpa-maven-plugin(pom 配置见《Apache OpenJPA 3.2.2 构建并运行示例应用指南》),构建命令与实测回显:

cd /root/openjpa-demo
mvn -q clean process-classes
79  openjpa-demo  INFO   [main] openjpa.Tool - Enhancer running on type "class demo.Employee".

五、核心 API 详解

5.1 Persistence 与 EntityManagerFactory

引导入口,读取 persistence.xml 中名为 openjpa-demo 的持久化单元:

EntityManagerFactory emf =
        Persistence.createEntityManagerFactory("openjpa-demo");
  • Persistence.createEntityManagerFactory(String):按持久化单元名创建工厂(单例化使用,进程内一般只建一次)。
  • emf.createEntityManager():每次业务操作创建 EntityManager。
  • emf.close():进程结束时释放(实测末尾调用后进程正常退出)。

5.2 EntityManager 与 EntityTransaction(CRUD 实测)

新增、更新、删除均需在事务中执行;查询不强制要求事务:

EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
em.persist(new Employee("张三", "研发部", 18000.0));   // 新增
tx.commit();
tx = em.getTransaction();
tx.begin();
Employee e = em.find(Employee.class, 2L);             // 按主键查询
e.setSalary(16000.0);                                 // 托管实体修改即更新
tx.commit();
tx = em.getTransaction();
tx.begin();
Employee e3 = em.find(Employee.class, 3L);
em.remove(e3);                                        // 删除
tx.commit();

方法速查:

方法作用
persist(Object)新增托管实体
find(Class, Object)按主键查询(返回托管实体)
merge(Object)合并游离实体(返回托管副本)
remove(Object)删除实体
createQuery(String, Class)创建 TypedQuery(类型化 JPQL)
createQuery(String)创建 Query(通用 JPQL)
flush()立即同步到数据库
close()释放 EntityManager

5.3 JPQL 查询(实测回显)

类型化查询 + 命名参数:

TypedQuery<Employee> q = em.createQuery(
        "select e from Employee e where e.department = :dept order by e.salary desc",
        Employee.class);
q.setParameter("dept", "研发部");
List<Employee> devs = q.getResultList();

实测回显(2 条命中,按薪资降序):

== JPQL 条件查询 研发部 (2 条) ==
   Employee[id=3, name=王五, department=研发部, salary=22000.00]
   Employee[id=1, name=张三, department=研发部, salary=18000.00]

聚合查询:

Query avgQuery = em.createQuery(
        "select avg(e.salary) from Employee e where e.department = :dept");
avgQuery.setParameter("dept", "研发部");
Object avg = avgQuery.getSingleResult();

实测回显:

== JPQL 聚合查询 研发部平均薪资: 20000.0 ==

计数查询:

long count = (Long) em.createQuery("select count(e) from Employee e").getSingleResult();

实测回显:

== 删除后员工总数: 2 ==

💡 说明:JPQL 中 Employee 为实体名(非表名)、e 为别名;OpenJPA 编译为原生 SQL(如 SELECT t0.id, t0.department, t0.name, t0.salary FROM employees t0 WHERE (t0.department = ?) ORDER BY t0.salary DESC),可通过 SQL=TRACE 日志核对。

六、注意事项

  • 工具均需完整 classpath:SchemaTool/MappingTool 连接数据库时会加载 JDBC 驱动,请用 openjpa-all-3.2.2.jar(内置依赖)或显式加入驱动 jar。
  • 增强只做一次:同一 class 重复执行 PCEnhancer 无害但多余;构建期增强后勿再覆盖 target/classes 下的原始 class。
  • 工具类日志:工具运行日志走 openjpa.Tool 频道,可用 -p 属性文件中的 openjpa.Log 调级别(如 Tool=DEBUG 看内部步骤)。
  • 事务边界:RESOURCE_LOCAL 模式下必须手动 tx.begin()/commit(),忘记 commit 会导致数据未落库(事务自动回滚时抛 RollbackException)。

七、常见问题

Q1:java -cp openjpa-all-3.2.2.jar PCEnhancer 找不到主类? A:确认主类全名大小写:org.apache.openjpa.enhance.PCEnhancer(不是 PCEnhancer 简写);且 jar 路径正确。

Q2:SchemaTool/MappingTool 连库报 ClassNotFoundException? A:classpath 缺少数据库驱动。加 -cp openjpa-all-3.2.2.jar:<驱动jar>(Derby 驱动在官方包 lib/derby-10.14.2.0.jar),或在 -p 属性中确认 javax.persistence.jdbc.driver。

Q3:增强前后行为有什么差异? A:增强前(未增强 + RuntimeUnenhancedClasses=supported)实测启动输出警告「Creating subclass ... less efficient and will consume more memory」,且一对多/多对一懒加载失效;增强后无警告,javap 可见类实现 PersistenceCapable。

Q4:如何离线获得工具? A:官方二进制包 apache-openjpa-3.2.2-binary.zip 解压后的 openjpa-all-3.2.2.jar 即全量工具集,无需 Maven 仓库(实测 PCEnhancer 直接运行成功)。

八、参考链接