JPA 2 定义了一个类型安全的新 Criteria
API,它允许以强类型化方式构造查询条件,使用元模型对象提供类型安全。对于开发人员而言,重要的是元模型生成的这项任务可以自动化。Hibernate 静态元模型生成器是一种基于注解处理器且基于[可插拔注解处理 API]的任务创建 JPA 2 静态元模型类。以下示例显示了两个 JPA 2 实体 Order
和 Item
,以及元模型类 Order_
和一个类型安全查询。
示例 1.2 元模型类 Order_
@StaticMetamodel(Order.class)
public class Order_ {
public static volatile SingularAttribute<Order, Integer> id;
public static volatile SingularAttribute<Order, Customer> customer;
public static volatile SetAttribute<Order, Item> items;
public static volatile SingularAttribute<Order, BigDecimal> totalCost;
}
示例 1.3. 类型安全的 citeria 查询
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Order> cq = cb.createQuery(Order.class);
SetJoin<Order, Item> itemNode = cq.from(Order.class).join(Order_.items);
cq.where( cb.equal(itemNode.get(Item_.id), 5 ) ).distinct(true);
Metamodel 生成器还考虑到了在 orm.xml 中指定的 xml 配置,或在 persistence.xml 中指定的映射文件。然而,如果所有配置都在 XML 中,则需要在至少一个映射文件中添加以下持久性单元元数据
<persistence-unit-metadata> <xml-mapping-metadata-complete/> </persistence-unit-metadata>
Metamodel 类的结构在 [JPA 2 规范] 中进行了描述,但为了完整起见,以下段落会重复该定义。如果您对血腥的细节不感兴趣,请随意跳过继续阅读 第 2 章,用法。
注释处理器为持久性单元中的每个受管类生成了基于以下规则的 Metamodel 类
对于包 p 中的每个受管类 X
,将在包 p 中创建一个 Metamodel 类 X_
。
Metamodel 类的名称是通过在受管类的名称后追加 “_”而派生的。
元模型类 X_
必须使用 javax.persistence.StaticMetamodel
标注进行标注。
如果类 X
扩展了其他类 S
,其中 S
是 X
扩展的最衍生的受管理类(即实体或映射超类),则必须类 X_
扩展类 S_
,其中 S_
是为 S
创建的元模型类。
对于类 X
声明的每个持久性非集合值属性 y,其中 y 的类型是 Y
,则元模型类必须包含如下声明
public static volatile SingularAttribute<X, Y> y;
对于类 X
声明的每个持久性集合值属性 z,其中 z 的元素类型是 Z
,则元模型类必须包含如下声明
如果 z 的集合类型是 java.util.Collection,则
public static volatile CollectionAttribute<X, Z> z;
如果 z 的集合类型是 java.util.Set,则
public static volatile SetAttribute<X, Z> z;
如果 z 的集合类型是 java.util.List,则
public static volatile ListAttribute<X, Z> z;
如果 z 的集合类型是 java.util.Map,则
public static volatile MapAttribute<X, K, Z> z;
其中 K 是类 X 中映射键的类型
必须包含 import 语句,以便针对所需的 javax.persistence.metamodel
类型进行导入,而且包含所有类 X
、Y
、Z
和 K
。
注解处理器的 jar 文件可以在 JBoss Maven 存储库中找到,方法是使用 示例 2.1,"Maven 依赖项"。
或者,可以从 SourceForge 下载一个完整的分发包。
大多数情况下,如果将处理器 jar 添加到了类路径且使用的是 JDK 6,则注解处理器将自动运行。这是由于 Java 的服务提供程序 合同以及 Hibernate 静态元模型生成器 jar 文件包含文件 javax.annotation.processing.Processor
的事实,该文件位于 META-INF/services
目录中。处理器本身的完全限定名称是:org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor
。
必须使用 Java 6 编译器。
如前所述,只要 jar 文件在类路径中,则每次调用 Java 编译器时注释处理器都会自动运行。然而,有时控制注释处理的详细情况很重要,例如,在不编译任何其他源文件的情况下专门运行处理器。示例 2.2,“Javac 任务配置” 展示了如何将 Ant 的Javac 任务配置为仅运行注释处理。
选项 -proc:only 指示编译器仅运行注释处理。您还可以通过指定 -proc:none 来完全禁用处理。
运行 'javac -help'
来查看可以指定哪些其他注释处理器相关选项。
maven-compiler-plugin 方法有其不足之处,即 maven 编译器插件目前不允许指定多个编译器参数 (MCOMPILER-62),并且来自 Messenger API 的消息被禁止 (MCOMPILER-66)。更好的方法是禁用编译器插件的注释处理,如 示例 2.4,“Maven 编译器插件配置 - 间接执行” 所示。
禁用后,可以使用maven-processor-plugin 进行注释处理。可以在 示例 2.5,“使用 maven-processor-plugin 进行配置” 中看到该配置。
当然,您也会希望在您最喜爱的 IDE 中进行注释处理。以下段落和屏幕截图展示如何在 IDE 中启用 Hibernate 静态元模型生成器。
Hibernate Static Metamodel Generator 接受一系列自定义选项,这些选项可以使用 -A[property]=[value]
格式传递到处理器。支持的属性有
表 2.1. 注释处理器选项(通过 -A[property]=[value] 传递)
选项名称 | 选项值和用法 |
debug | 如果设置为 true ,处理器将输出其他跟踪信息 |
persistenceXml | 默认情况下,处理器在 /META-INF 中寻找 persistence.xml。指定此选项,可以指定来自不同位置的 persitence.xml 文件(必须在类路径上) |
ormXml | 允许指定附加实体映射文件。此选项指定的值是映射文件名以逗号分隔的字符串。即使指定了此选项,/META-INF/orm.xml 也是隐式的。 |
lazyXmlParsing | 可能的值为 true 或 false 。如果设置为 true ,注释处理器会尝试确定在调用之间任何一个 xml 文件是否已更改,如果未更改,则跳过 xml 解析。此功能是实验性的,在某些混合模式配置中存在返回错误结果的风险。为确定某个文件是否已修改,会使用临时文件 Hibernate-Static-Metamodel-Generator.tmp 。此文件将创建在 java.io.tmpdir 目录中。 |
fullyAnnotationConfigured | 如果设置为 true ,处理器将忽略 orm.xml 和 persistence.xml. |
addGeneratedAnnotation | 如果设置为 true ,则处理器将 @Generated 添加到生成的 Java 源文件中。如果使用 JDK 5 添加此注释,则会引发编译错误。在这种情况下,将该标志设置为 false 。此选项的默认值是 true |
addGenerationDate | 如果设置为 true ,则元模型类的生成日期将插入到 @Generated 注释的 date 参数中。默认值为 false 。如果 addGeneratedAnnotation 设置为 false ,则忽略此参数。 |
addSuppressWarningsAnnotation | 如果设置为 true ,则处理器将 @SuppressWarnings("all") 添加到生成的 Java 源文件中。默认情况下不会生成此注释。另请参阅 METAGEN-50。 |
如需进一步使用问题或解决办法,请参阅 Hibernate 论坛。如需报告错误,请使用 Hibernate Jira 实例中的 METAGEN 项目。我们始终欢迎您的反馈。
版权所有 © 2010 Red Hat Inc.