2

假设我有以下简单的客户/订单实现:

由 Customer 类定义的客户记录。每个客户可以有多个由 Order 类定义的订单。

借鉴here的Transparent Indirection和here的Container Policies的解释,EclipseLink这些概念的理解如下:

透明间接允许我说

Customer customer = Customer.getCustomerById(1);
Set<Order> orders = customer.getOrders();

需要注意的两点是:

  1. 间接允许延迟加载属性,因此客户的订单仅在第 2 行而不是第 1 行从数据库中获取。
  2. 我可以将客户的订单视为 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;
    }
}
4

1 回答 1

1

您的理解是正确的,但不需要,因为这不是您在使用 JPA 时需要配置的内容。EclipseLink 将根据属性的类型和惰性/急切设置来确定要使用的收集策略和实现,而且它似乎这样做是正确的。异常抛出错误,可能是由于类加载器问题,因此用于 init 的类加载器不是用于验证的类加载器,但我不知道这是怎么发生的。您需要查看正在运行的环境,因为异常本身只是一个症状

于 2014-06-05T14:36:02.410 回答