JPA Criteria API预测OneToMany关系中的对象

问题描述 投票:1回答:2

给出以下代码

@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中的连接。换句话说,查询中不会提取InvoiceLineItems。

jpa jpa-2.0 criteria criteria-api
2个回答
0
投票

我现在无法进行测试,但坚持使用Java EE 6 Tutorial,我们看到了

可嵌入类还可以包含与其他实体或实体集合的关系。如果可嵌入类具有这种关系,则关系是从目标实体或实体集合到拥有可嵌入类的实体。

这让我认为Join谓词应该用起始实体Invoice而不是InvoiceData来定义。这也得益于通常起始实体应该是查询根本身。我会尝试这样的事情:

Join<Invoice, InvoiceLineItem> lineItems = root.join(Invoice_.data).join(InvoiceData_.lineItems);

0
投票

我为EclipseLink 2.0.0换了Hibernate 4.1.0.Final并且它运行了。

© www.soinside.com 2019 - 2024. All rights reserved.