EclipseLink:BatchFetch(BatchFetchType.IN)深层关系使用find或JPQL失败

时间:2013-10-11 10:36:50

标签: java jpa eclipselink

我正在使用与GlassFish(v3.1.2.2)捆绑在一起的EclipseLink(v2.3.2),并且使用@BatchFetch(使用BatchFetchType.IN)遇到了一些问题。

我有3个实体A,B,C:

@Entity
public class A {
    @Id
    private String aId;

    @BatchFetch(value=BatchFetchType.IN)
    @OneToMany(mappedBy = "a", fetch = FetchType.LAZY)
    private Collection<B> bs;

    public String getAId() {
        return aId;
    }

    public void setAId(String aId) {
        this.aId = aId;
    }

    public Collection<B> getBs() {
        return bs;
    }

    public void setBs(Collection<B> bs) {
        this.bs = bs;
    }
}

@Entity
public class B {
    @Id
    private String bId;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "aId")
    private A a;

    @BatchFetch(value=BatchFetchType.IN)
    @ManyToOne(fetch = FetchType.LAZY, cascade={CascadeType.PERSIST})
    @JoinColumn(name = "CID")
    private C c;

    public String getBId() {
        return bId;
    }

    public void setBId(String bId) {
        this.bId = bId;
    }

    public Root getA() {
        return a;
    }

    public void setA(A a) {
        this.a = a;
    }

    public C getC() {
        return c;
    }

    public void setC(C c) {
        this.c = c;
    }
}

@Entity
public class C {
    @Id
    private String cId;

    @OneToMany(mappedBy = "c", fetch = FetchType.LAZY)
    private Collection<B> parents = new ArrayList<B>();

    public String getCId() {
        return cId;
    }

    public void setCId(String cId) {
        this.cId = cId;
    }

    public Collection<B> getParents() {
        return parents;
    }

    public void setParents(Collection<B> parents) {
        this.parents = parents;
    }
}

现在我想查询A和延迟加载(使用批量选择)其Bs和Cs。

CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<A> query = builder.createQuery(A.class);
Root<A> root = query.from(A.class);
query.where(SOME CRITERIA FOR SEARCHING);
List<A> result = em.createQuery(query).getResultList();
for (A a : result) {
    for (B b : a.getBs()) {
        C c = b.getC();
        // do something with c
    }
}

这就像一个魅力,但如果我尝试做以下事情:

A a = em.find(A.class, "SOME A ID");
for (B b : a.getBs()) {
    C c = b.getC(); // <---- QueryException is thrown
    // do something with c
}

无法使用以下内容获取C:

org.eclipse.persistence.exceptions.QueryException
Exception Description: The parameter name [query-batch-parameter] in the query's selection criteria does not match any parameter name defined in the query.
Query: ReadAllQuery(name="c" referenceClass=C sql="SELECT DISTINCT CID FROM C WHERE (CID IN ?))

如果我使用的是JPQL而不是CriteriaBuilder,则会出现同样的问题。

此行为适用于BatchFetchType.IN,在所有情况下都使用BatchFetchType.EXISTS函数。我想使用IN,因为与其他提取类型相比,它有一些好处。

我做错了什么,或者它可能是EclipeLink中的错误? 谢谢你的帮助!

0 个答案:

没有答案