JPA左加入多个OneToMany实体

时间:2016-05-29 16:14:01

标签: hibernate jpa

我想为我正在为之工作的公司制作订单跟踪系统。

目前,我需要在启动时从我的mySQL数据库加载PO entites,这些数据库的发票为空或不是'已交付'状态(枚举)。

我的成员如下

@Entity
public class PO {

@Id
@GeneratedValue
private Long id;

@Column(name = "Customer", nullable = false)    
private String customer;

@Column(name = "PO_number", nullable = false)
private String PONUMBER;

@OneToMany(mappedBy = "po",cascade = CascadeType.PERSIST,fetch = FetchType.EAGER)
private  List<CatogeryEntires> poCatogories = new ArrayList<>();

@Column(name = "entered_on", nullable = false)
private LocalDateTime entryDate;

@Column(name = "Delivery_Date", nullable = false)
private LocalDate dd;

@Transient
private ObjectProperty<LocalDate> deliveryDate;

@Column(name = "Deliver_Before", nullable = false)
private LocalTime dt;

@Transient
private ObjectProperty<LocalTime> deliveryTime;
@Entity
public class CatogeryEntires {

 @Id
    @GeneratedValue
    private Long id;

    @Enumerated(EnumType.STRING)
    private PO_CATOGERY poCatogery;

    @ManyToOne
    @JoinColumn(name = "po_id", nullable = false)
    private PO po;

    @OneToMany(mappedBy = "catogeryEntries", cascade = CascadeType.PERSIST)
    private Set<Invoice> invoices = new HashSet<>();
@Entity
public class Invoice {

@Id
@GeneratedValue
private Long id;

private int invoiceNumber;

@Column(name = "delivered_on", nullable = true)
private LocalDateTime deliveredOn;

@Enumerated(EnumType.STRING)
@Column(name = "status", nullable = true)
private InvoiceStatus invoiceStatus;

@ManyToOne
@JoinColumn(name = "catogery_entry_id")
private CatogeryEntires catogeryEntries;

我目前在数据库中使用以下本机SQL语句来获得所需的结果

SELECT po_app.po.id,Customer,PO_number,Delivery_Date,Deliver_Before ,poCatogery,invoiceNumber,状态

FROM (po.app.po在po.id = catogeryentires.po_id上加入po_app.catogeryentires)

LEFT JOIN po_app.invoice on catogeryentires.id = invoice.catogery_entry_id

WHERE 状态为null或状态!=&#39;已交付&#39;;

我不知道通过JPQL复制这个 我尝试阅读以下参考书:Java persistance和hibernate 2nd editions&#34;但仍然没有运气。

1 个答案:

答案 0 :(得分:0)

我使用了同一本书,我认为这段代码应该有效:

    EntityManagerFactory emf = Persistence.createEntityManagerFactory("Your PU Name Here");
    EntityManager em = emf.createEntityManager();

    try {

        String jpql = "SELECT p.id, p.customer, p.PONUMBER, p.deliveryDate, p.dt, c.poCatogery, i.invoiceNumber, i.status "
                    + "FROM PO p "
                    + "JOIN p.poCatogories  c "
                    + "JOIN c.invoices i WHERE i.status IS NULL or i.status != :status)";

        Query query = em.createQuery(jpql);
        query.setParameter("status", InvoiceStatus.DELIVERED);
        List<Object> resultList = query.getResultList();

        System.out.println(resultList.size() + " invoice(s) found:" );

        for (Object singleResult : resultList) {
            Object[] singleRow = (Object[]) singleResult;
            ...
        }


    } finally {
        em.close();
        emf.close();
    }

您可以通过微小的更改进行测试。替换EntityManagerFactory上的PU名称,并可能在查询中修复一些可能的拼写错误。

请注意,您将获得一个包含两个INNER JOIN的SQL查询。我一直在阅读有关该主题的一些文章和书籍,并使用带有where子句的左连接提取无效。引用&#34; Java持久性与Hibernate&#34;作者:Gavin King等人:&#34; 查询left join fetch i.bids b where b.amount ...无效。您无法说,&#34;加载商品实例并初始化其出价集合,但仅限于具有特定金额的出价实例&#34;。

希望这有帮助。