GlassFish (v3.1.2.2) にバンドルされている EclipseLink (v2.3.2) を使用していますが、@BatchFetch
(with 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 を照会し、その B と C も (バッチ選択を使用して) 遅延ロードします。
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 ?))
CriteriaBuilder の代わりに JPQL を使用している場合、同じ問題が発生します。
この動作は に適用され、すべての場合に関数を適切にBatchFetchType.IN
使用します。BatchFetchType.EXISTS
IN を使用したいのは、他のフェッチ タイプと比較していくつかの利点があるためです。
何か間違ったことをしていますか、それとも EclipeLink のバグでしょうか? ご協力いただきありがとうございます!