Java Persistence API (JPA) 2.0 版目前已进入最终建议草案阶段,这一版对规范作出了重要更新,为条件查询(criteria queries)增加了一个 API,一个元模型 API,并且支持 Bean Validation [JSR 303]。
这一版的条件查询(criteria query)API 允许通过调用 Java 对象的方法来创建查询,而不是把 JPA-QL 嵌入到字符串中,由 JPA 实现进行处理。在第一个公开草案中,API 本身是基于字符串的,专家组收到许多反馈建议他们研究一下改善该议案的类型安全性的可能行。Gavin King 提出了一个建议,该建议建立在现有基于字符串的 API 之上,利用 Java 6 中的 javax.annotation.Processor 对应用程序中的每一个持久类都自动产生一个元模型类型。结合泛型,这一机制提供了一种有效的变通方法,解决了 Java 缺乏针对类的方法和属性的类型安全元模型的问题。每当使用代码生成器时,就会引起争议,因为其产生的代码往往晦涩难懂,而且通常需要特定 IDE 的支持。但是在这里,因为产生的代码只是用于类型信息,保持其整洁还是有可能的。例如,给定一个持久类:
import java.util.Set; <br></br> import java.math.BigDecimal; <br></br> @Entity public class Order { <br></br> @Id Integer orderId; <br></br> @ManyToOne Customer customer; <br></br> @OneToMany Set<item> lineitems; <br></br> Address shippingAddress; <br></br> BigDecimal totalCost; <br></br> ... <br></br> } </item>
相应的典型元模型类,Order_,如下所示:
import java.math.BigDecimal; <br></br> import javax.persistence.metamodel.Attribute; <br></br> import javax.persistence.metamodel.Set; <br></br> import javax.persistence.metamodel.TypeSafeMetamodel; <br></br> import javax.annotation.Generated; <br></br> @Generated <br></br> @TypeSafeMetamodel <br></br> public class Order_ { <br></br> public static volatile Attribute
因为 Java 6 包含注解处理器(annotation processor),因此这一变化并不需要特定的 IDE 支持——IDE 可以把注解委托给由编译器触发的注解处理器,并且在处理过程中产生元数据模型。
元模型可以通过一个 API 来查询,该 API 指定了接口,用于动态访问持久状态元模型和持久单元托管类(Managed classes)的关联关系。它还不能提供支持访问 ORM 信息,尽管这已在未来更新的规划之中。该接口由持久化提供商实现,可以通过 EntityManagerFactory.getMetamodel 和 EntityManager.getMetamodel 方法来访问,其返回的是提供商针对 javax.persistence.metamodel.Metamodel 接口的实现类。
King 最近建议进行进一步重构,把类型安全性一直扩展到查询结果集,给 CriteriaQuery 和 Query 都增加一个类型参数。这就使开发者可以直接访问类型安全的实体列表或封装,但对于基于 JPA 1.0 的项目,这将导致编译器警告,因为 javax.persistence.Query 目前没有这个类型参数。
类型安全方法曾在专家组中引发过争论。JPA 2.0 规范的领导 Linda DeMichiel 在其博文中记述了对 String 和类型安全方法的比较,文中她是这样描述的:
“在基于元模型 API 和基于字符串 API 相比孰优孰劣的几番争论之后,我们 [专家组] 决定采用类型安全的 API,但是如果开发这愿意,我们也提供了基于字符串方法的选项。”
这两个选项之间的主要区别是,基于字符串的属性名可以用来指定 joins 和 navigation 中引用的属性。结果是这些查询与类型安全版拥有相同的语义,但是却没有相同级别的类型安全性。
JPA 2.0 还支持在 Java 持久化应用中使用 Bean Validation[JSR 303]。托管类(实体、映射的超类和可嵌入类)可被配置包含 Bean Validation 约束。使用这些约束的自动校验是这样实现的,指定 Java 持久化应用程序将校验委托给基于 pre-persist、pre-update 和 pre-remove 实体生命周期事件的 Bean Validation 实现。
专家组热切期望接到来自社区的反馈,如有何意见可发送至 jsr-317-pfd-feedback@sun.com。
评论