给出以下代码
@Entity
public class Invoice {
@GeneratedValue(strategy = GenerationType.AUTO)
@Id
public Long id;
@Embedded
private InvoiceData data = new InvoiceData();
}
@Embeddable
public class InvoiceData {
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
public Collection<InvoiceLineItem> lineItems;
}
@Entity
public abstract class InvoiceLineItem {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column
private String description;
}
@Entity
public class GoodsLineItem extends InvoiceLineItem {
}
@Entity
public class CostLineItem extends InvoiceLineItem {
}
我如何编写一个标准api查询,该查询返回所有带有CostLinesItem的发票,其描述为'TAX'?
我正在使用元数据API。我尝试了各种方法,其中大部分是下面列出的2的变体。任何指针/帮助或'去读这个都将非常感谢。
尝试1(很多):
@Test
public void criteria_api_and_collections() throws Exception {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Invoice> query = builder.createQuery(Invoice.class);
Root<Invoice> root = query.from(Invoice.class);
Join<InvoiceData, InvoiceLineItem> lineItems = root.join(Invoice_.data).join(InvoiceData_.lineItems);
query.where(builder.equal(lineItems.get(InvoiceLineItem_.description), ""));
List<Invoice> resultList = em.createQuery(query).getResultList();
System.out.println(resultList);
}
尝试2(很多人):
@Test
public void criteria_api_and_collections() throws Exception {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Invoice> query = builder.createQuery(Invoice.class);
Root<Invoice> root = query.from(Invoice.class);
Join<InvoiceData, InvoiceLineItem> lineItems = root.join(Invoice_.data).join(InvoiceData_.lineItems, JoinType.LEFT);
Subquery<CostLineItem> subquery = query.subquery(CostLineItem.class);
Root<CostLineItem> fromLineItem = subquery.from(CostLineItem.class);
subquery.select(fromLineItem);
subquery.where(builder.equal(lineItems.get(InvoiceLineItem_.description), "TAX"));
query.where(builder.in(lineItems).value(subquery));
List<Invoice> resultList = em.createQuery(query).getResultList();
}
两次尝试都会导致SQL语法异常。在结果SQL中引用别名,该别名从未创建。看起来应该将别名分配给不存在的SQL中的连接。换句话说,查询中不会提取InvoiceLineItem。
答案 0 :(得分:0)
我现在无法进行测试,但坚持Java EE 6 Tutorial,我们看到了
可嵌入类也可能包含与其他实体的关系或 实体集合。如果嵌入类有这样的 关系,关系来自目标实体或集合 实体到拥有可嵌入类的实体。
这使我认为应该使用起始实体Join
而不是Invoice
来定义InvoiceData
谓词。这也得益于通常起始实体应该是查询根本身。我会尝试这样的事情:
Join<Invoice, InvoiceLineItem> lineItems = root.join(Invoice_.data).join(InvoiceData_.lineItems);
答案 1 :(得分:0)
我为EclipseLink 2.0.0换了Hibernate 4.1.0.Final并且它运行了。