@OrderBy
默认情况下,JPA 持续性提供程序按关联实体的主键以升序顺序检索 Collection 关联的成员。
将 @OrderBy 批注与 @OneToMany 和 @ManyToMany 一起使用以便:
表 1-31 列出了此批注的属性。有关更多详细信息,请参阅 API。
示例 1-65 显示了如何使用 @OrderBy 批注指定 Project 方法 getEmployees 应按 Employee 字段 lastname 以升序顺序并按 Employee 字段 seniority 以降序顺序返回 Employee 的 List。示例 1-66 显示了默认情况下,Employee 方法 getProjects 按 Employee 主键 empId 以升序顺序返回 List。
示例 1-65 Project 实体
@Entity public class Project {
...
@ManyToMany
@OrderBy("lastname ASC", "seniority DESC")
public List<Employee> getEmployees() {
...
};
...
}
示例 1-66 Employee 实体
@Entity public class Employee {
@Id
private int empId;
...
private String lastname;
...
private int seniority;
...
@ManyToMany(mappedBy="employees")
// By default, returns a List in ascending order by empId
public List<Project> getProjects() {
...
};
...
}
@PersistenceContext
在使用 JPA 持续性提供程序的应用程序中,可以使用实体管理器执行所有持续性操作(创建、读取、更新和删除)。Java EE 应用程序使用相关性注入或在 JNDI 名称空间中直接查找实体管理器获取实体管理器。
使用 @PersistenceContext 批注获取实体管理器:
如果有多个要指定的 @PersistenceContext,则必须使用 @PersistenceContexts。
表 1-32 列出了此批注的属性。有关更多详细信息,请参阅 API。
示例 1-67 显示了如何使用此批注在无状态会话中注入实体管理器,示例 1-68 显示了如何使用此批注在 JNDI 中查找实体管理器。
示例 1-67 使用 @PersistenceContext 和相关性注入
@Stateless
public class OrderEntryBean implements OrderEntry {
@PersistenceContext
EntityManager em;
public void enterOrder(int custID, Order newOrder) {
Customer cust = em.find(Customer.class, custID);
cust.getOrders().add(newOrder);
newOrder.setCustomer(cust);
}
}
示例 1-68 使用 @PersistenceContext 和 JNDI 查找
@Stateless
public class OrderEntryBean implements OrderEntry {
@PersistenceContext(name="OrderEM")
EntityManager em;
public void enterOrder(int custID, Order newOrder) {
em = (EntityManager)ctx.lookup("OrderEM");
Customer cust = em.find(Customer.class, custID);
cust.getOrders().add(newOrder);
newOrder.setCustomer(cust);
}
}
@PersistenceContexts
如果要指定多个 @PersistenceContext,则必须使用一个 @PersistenceContexts 批注指定所有持续性上下文。
表 1-33 列出了此批注的属性。有关更多详细信息,请参阅 API。
示例 1-69 显示了如何使用此批注指定两个持续性上下文。
示例 1-69 @PersistenceContexts
@Stateless
public class OrderEntryBean implements OrderEntry {
@PersistenceContexts({
@PersistenceContext(name="OrderEM")
@PersistenceContext(name="ItemEM"),
})
public void enterOrder(int custID, Order newOrder) {
EntityManager em = (EntityManager)ctx.lookup("OrderEM");
Customer cust = em.find(Customer.class, custID);
cust.getOrders().add(newOrder);
newOrder.setCustomer(cust);
}
public void enterItem(int orderID, Item newItem) {
EntityManager em = (EntityManager)ctx.lookup("ItemEM");
...
}
}
@PersistenceProperty
默认情况下,JPA 持续性提供程序假设您使用 @PersistenceContext 获取的实体管理器将使用默认属性。
使用 @PersistenceProperty 批注指定属性(包括供应商特定的属性),以便容器或持续性提供程序:
创建实体管理器时将属性传递给持续性提供程序。无法识别的属性被简单地忽略。
表 1-34 列出了此批注的属性。有关更多详细信息,请参阅 API。
示例 1-70 显示了如何使用 @PersistenceProperty 批注自定义查询以利用由 TopLink Essentials 提供的供应商 JPA 扩展:在该示例中,该属性确保在此持续性上下文中使用一个完整的 TopLink 缓存。有关详细信息,请参阅“TopLink JPA Persistence.xml 文件扩展”。
示例 1-70 @PersistenceProperty
@Stateless
public class OrderEntryBean implements OrderEntry {
@PersistenceContext(
properties={
@PersistenceProperty={name="toplink.cache.type.default", value="CacheType.Full"}
}
)
EntityManager em;
public void enterOrder(int custID, Order newOrder) {
Customer cust = em.find(Customer.class, custID);
cust.getOrders().add(newOrder);
newOrder.setCustomer(cust);
}
}
@PersistenceUnit
默认情况下,JPA 持续性提供程序使用与默认持续性单元或您使用 @PersistenceContext 属性 unitName 指定的持续性单元关联的默认 EntityManagerFactory。
使用 @PersistenceUnit 批注指定EntityManagerFactory,您希望 JPA 持续性提供程序使用它来:
如果有多个要指定的 @PersistenceUnit,则必须使用 @PersistenceUnits。
表 1-34 列出了此批注的属性。有关更多详细信息,请参阅 API。
示例 1-71 显示了如何使用 @PersistenceUnit 批注指定要使用的 EntityManagerFactory 的 JNDI 名称以及与该工厂关联的持续性单元名称。当 JPA 持续性提供程序使用 JNDI 获取一个使用持续性上下文 OrderEM 的实体管理器时,它将使用 JNDI 名称 OrderEMFactory 与持续性单元 OrderEMUnit 关联的 EntityManagerFactory。
示例 1-71 使用 @PersistenceUnit 指定工厂和单元
@Stateless
public class OrderEntryBean implements OrderEntry {
@PersistenceContext(name="OrderEM")
@PersistenceUnit(name="OrderEMFactory", unitName="OrderEMUnit")
EntityManager em;
public void enterOrder(int custID, Order newOrder) {
em = (EntityManager)ctx.lookup("OrderEM");
Customer cust = em.find(Customer.class, custID);
cust.getOrders().add(newOrder);
newOrder.setCustomer(cust);
}
}
示例 1-72 显示了一个使用 @PersistenceContext 属性 unitName 仅指定持续性单元的其他方法。在该示例中,当 JPA 持续性提供程序使用 JNDI 获取一个使用持续性上下文 OrderEM 的实体管理器时,它将使用与持续性单元 OrderEMUnit 关联的默认 EntityManagerFactory。
示例 1-72 使用 @PersistenceContext 属性 unitName
@Stateless
public class OrderEntryBean implements OrderEntry {
@PersistenceContext(name="OrderEM", unitName="OrderEMUnit")
EntityManager em;
public void enterOrder(int custID, Order newOrder) {
em = (EntityManager)ctx.lookup("OrderEM");
Customer cust = em.find(Customer.class, custID);
cust.getOrders().add(newOrder);
newOrder.setCustomer(cust);
}
}
@PersistenceUnits
如果要指定多个 @PersistenceUnit,则必须使用一个 @PersistenceUnits 批注指定所有持续性上下文。
表 1-36 列出了此批注的属性。有关更多详细信息,请参阅 API。
示例 1-73 显示了如何使用此批注指定两个持续性单元。在该示例中,@PersistenceContext 属性 unitName 和 @PersistenceUnit 属性 unitName 必须对应以便关联持续性上下文和持续性单元。
示例 1-73 @PersistenceUnits
@Stateless
public class OrderEntryBean implements OrderEntry {
@PersistenceContexts({
@PersistenceContext(name="OrderEM", unitName="OrderEMUnit")
@PersistenceContext(name="ItemEM", unitName="ItemEMUnit"),
})
@PersistenceUnits({
@PersistenceUnit(name="OrderEMFactory", unitName="OrderEMUnit"),
@PersistenceUnit(name="ItemEMFactory", unitName="ItemEMUnit")
})
public void enterOrder(int custID, Order newOrder) {
EntityManager em = (EntityManager)ctx.lookup("OrderEM");
Customer cust = em.find(Customer.class, custID);
cust.getOrders().add(newOrder);
newOrder.setCustomer(cust);
}
public void enterItem(int orderID, Item newItem) {
EntityManager em = (EntityManager)ctx.lookup("ItemEM");
...
}
}
@PrimaryKeyJoinColumn
默认情况下,当一个实体使用 InheritanceType.JOINED(请参阅 @Inheritance)扩展另一个实体时,JPA 持续性提供程序假设子类的外键列与超类主表的主键列同名。
使用 @PrimaryKeyJoinColumn 批注:
表 1-37 列出了此批注的属性。有关更多详细信息,请参阅 API。
示例 1-74 显示了一个实体基类 Customer,示例 1-75 显示了如何使用 @PrimaryKeyJoinColumn 在 ValuedCustomer(Customer 的一个子类)的主表中指定主键连接列 CUST_ID。
示例 1-74 @PrimaryKeyJoinColumn - InheritanceType.JOINED 超类
@Entity
@Table(name="CUST")
@Inheritance(strategy=JOINED)
@DiscriminatorValue("CUST")
public class Customer {
...
}
示例 1-75 @PrimaryKeyJoinColumn - InheritanceType.JOINED 子类
@Entity
@Table(name="VCUST")
@DiscriminatorValue("VCUST")
@PrimaryKeyJoinColumn(name="CUST_ID")
public class ValuedCustomer extends Customer {
...
}
@PrimaryKeyJoinColumns
默认情况下,JPA 持续性提供程序假设每个实体有一个单列主键。
如果要指定一个由两个或更多列组成的主键,请使用 @PrimaryKeyJoinColumns 批注。
表 1-38 列出了此批注的属性。有关更多详细信息,请参阅 API。
示例 1-76 显示了如何使用此批注指定一个由列 CUST_ID 和 CUST_TYPE 组成的复合主键。
示例 1-76 @PrimaryKeyJoinColumns
@Entity
@Table(name="VCUST")
@DiscriminatorValue("VCUST")
@PrimaryKeyJoinColumns({
@PrimaryKeyJoinColumn(name="CUST_ID",referencedColumnName="ID"),
@PrimaryKeyJoinColumn(name="CUST_TYPE",referencedColumnName="TYPE")
})
public class ValuedCustomer extends Customer {
...
}