簡體   English   中英

Hibernate FetchMode.JOIN 與一對多映射

[英]Hibernate FetchMode.JOIN with one to many mapping

有兩個實體 InvoiceHeader 和 InvoiceDetail 具有一對多映射,如下所示。

發票頭

@Entity
@Table(name = "view_invoice_hdr")
@IdClass(InvoiceHdrPK.class)
@Getter
@NoArgsConstructor
@EqualsAndHashCode
public class InvoiceHeader{
  
  ....
  
  @OneToMany(mappedBy = "invoiceHeader", fetch = FetchType.EAGER)
  @Fetch(value = FetchMode.JOIN)
  private List<InvoiceDetail> items;
} 

發票HdrPK

@Getter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
public class InvoiceHdrPK implements Serializable {

    private String invoiceNumber;
    private InvoiceSource invoiceSource;
    private InvoiceType invoiceType;
    private Long companyId;
    private Integer invoiceYear;
}

同樣InvoiceDetail

@Entity
@Table(name = "view_inv_dtl")
@IdClass(InvoiceDetailPK.class)
@Getter
@NoArgsConstructor
@EqualsAndHashCode
public class InvoiceDetail{
  
  ....
  
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumns(value = {
            @JoinColumn(name = "invoice_number", referencedColumnName = "invoice_number", insertable = false, updatable = false),
            @JoinColumn(name = "invoice_source", referencedColumnName = "invoice_source", insertable = false, updatable = false),
            @JoinColumn(name = "invoice_type", referencedColumnName = "invoice_type", insertable = false, updatable = false),
            @JoinColumn(name = "company_id", referencedColumnName = "company_id", insertable = false, updatable = false),
            @JoinColumn(name = "invoice_year", referencedColumnName = "invoice_year", insertable = false, updatable = false),
    })
    private InvoiceHeader invoiceHeader;
} 

發票明細PK

@Getter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
public class InvoiceDetailPK implements Serializable {

    private String invoiceNumber;
    private InvoiceSource invoiceSource;
    private InvoiceType invoiceType;
    private BigDecimal rate;
    private Long itemNo;
    private Long companyId;
    private Integer invoiceYear;

}

這兩個實體都不是數據庫級別的實際表,而是作為視圖維護。

使用 JPA我正在嘗試使用帶有FetchMode.JOINfindAll(Specification, pageable)來獲取發票以避免n+1查詢問題。

但得到異常

org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list...

那么我該如何解決這個問題,我錯過了什么?

也許你使用 Set 而不是 List @OneToMany(mappedBy = "invoiceHeader", fetch = FetchType.EAGER) @Fetch(value = FetchMode.JOIN) private Set items = new HashSet<>();

似乎您使用類似於此select b from A a join ab b join fetch a.c的查詢。 要點是,您加入獲取一些您從未通過 select 子句中的父項引用的關聯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM