假设我有以下简单的客户/订单实现:
由 Customer 类定义的客户记录。每个客户可以有多个由 Order 类定义的订单。
借鉴here的Transparent Indirection和here的Container Policies的解释,我对EclipseLink这些概念的理解如下:
透明间接允许我说
Customer customer = Customer.getCustomerById(1);
Set<Order> orders = customer.getOrders();
需要注意的两点是:
- 间接允许延迟加载属性,因此客户的订单仅在第 2 行而不是第 1 行从数据库中获取。
- 我可以将客户的订单视为 Order 类型对象的 Set(或 Collection、List 或 Map)。
Container Policy 告诉 EclipseLink 应该为 Set 使用哪个实际类,因此它应该Set
在上面的示例中实现。
这就是我对 EclipseLink 中的透明间接和容器策略的理解。
当我尝试访问数据库时看到以下错误:
异常 [EclipseLink-148] (Eclipse Persistence Services - 2.3.0.v20110604-r9504):org.eclipse.persistence.exceptions.DescriptorException 异常描述:容器策略 [CollectionContainerPolicy(class org.eclipse.persistence.indirection.IndirectSet)]与透明间接不兼容。映射:org.eclipse.persistence.mappings.OneToManyMapping[orders] 描述符:RelationalDescriptor(my.model.Customer --> [DatabaseTable(Customer)])
我确定我在尝试调试的代码中存在错误,但我没有指定错误中提到的 CollectionContainerPolicy,所以我认为org.eclipse.persistence.indirection.IndirectSet
是默认值。但是,如果我使用的是默认策略,那么我不确定导致此错误的原因可能是什么,或者我应该使用哪个策略。
现在,我只想知道我对上面提到的透明间接和容器策略的理解是否正确。
如果它是正确的,我可能在我的代码中遗漏了一些相对较小的东西(调用或配置选项等),但如果我不理解这些概念,那么显然我需要先做更多的研究。
客户模型
package my.model;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
/**
* The persistent class for the customer database table.
*
*/
@Entity
@Table(name=Customer.TBL_NAME)
@NamedQueries({
@NamedQuery(name=Customer.QRY_BY_NAME,query="Select object(a) from Customer a where " +
"a.name=:" + Customer.PRM_NAME),
@NamedQuery(name=Customer.QRY_ALL, query="select object(a) from Customer a")
})
public class Customer implements Serializable {
private static final long serialVersionUID = 1L;
// Table specific onstants
public static final String TBL_NAME = "Customer";
public static final String QRY_BY_NAME = TBL_NAME + ".byName";
public static final String QRY_ALL = TBL_NAME + ".all";
public static final String PRM_NAME = "name";
private int id;
private String name;
private Set<Order> orders;
public Customer() {
}
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
//bi-directional many-to-one association to Order
@OneToMany(mappedBy="customer")
public Set<Order> getOrders() {
return this.orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
}
订购型号
package my.model;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
/**
* The persistent class for the order database table.
*
*/
@Entity
@Table(name=Order.TBL_NAME)
public class Order implements Serializable {
private static final long serialVersionUID = 1L;
// Table constants
public static final String TBL_NAME = "Order";
private int id;
private Customer customer;
public Order() {
}
@Id
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
//bi-directional many-to-one association to Customer
@ManyToOne
public Customer getCustomer() {
return this.customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
}