JPA EclipseLink @ElementCollection通过CriteriaQuery连接获取

时间:2012-04-02 16:11:41

标签: jpa-2.0 eclipselink criteria-api

我有一个实体(Book),其中包含一个List属性(标签)的ElementCollection。

@Entity
@Table(name = "BOOK")
public class Book {

@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "BOOK_TAGS", joinColumns = @JoinColumn(name = "BOOK_ID"))
@Column(name = "TAG", length = "4000")
private List<String> tags;

}

为了获得一本书,我正在使用entityManager.find并获取所有书籍,我正在进行标准查询。这一切都有效。我现在想要延迟加载标签列表,这样可以防止它们在我拿到所有书籍(我想要的)时加载,但是当我得到一本特定的书时我还想加载它们。

我的第一次尝试是将entityManager.find更改为查询。以下作品:

select b from Book b left outer join fetch b.tags where b.id = :id

但是,我想将此作为CriteriaQuery执行,并添加用于获取所有书籍查询的标签的选项。执行以下操作无效:

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery cq = cb.createQuery(Book.class);
Root<Book> b = cq.from(Book.class);
b.fetch("tags", JoinType.LEFT);
cq.select(b);
cq.where(cb.equal(b.get("id"),cb.parameter(String.class,"id"));
TypedQuery<Book> q = em.createQuery(cq);
q.setParameter(id);
return q.getSingleResult();

这是失败的,因为它不是一个结果 - 它看起来像N个对象,其中N是标签的数量。

我也尝试添加:

q.setHint("eclipselink.join-fetch","b.tags");

并取出了fetch,但这也行不通。

我正在将这些列添加到SQL中,但它像处理那些额外的列一样弄乱了返回的对象 - 它是多个或没有对象(用于提示)。

如何将JOIN FETCH转换为适当的CriteriaQuery?

1 个答案:

答案 0 :(得分:1)

回答我自己的问题 - 加入fetch不是这里的方法,因为这会弄乱结果计数 - 技巧是通过QueryHints使用批量提取 - 并预加载标签以及QueryHint。