2015-04-02 78 views
4

我有一個Product實體類,我希望它與Price表一起加入。如何使用JPA和休眠映射集合的最新子節點

我的目標是堅持舊的價格報告,當我得到Product實體時,它應該根據最新日期映射到最新價格。

請解釋我如何在Hibernate JPA關係中實現這一點。如果可能的話,共享一個代碼片段。

回答

5

這是一個很棒的問題,所以我決定把這個答案變成an article

你的域模塊應該是這樣的:

@Entity 
public class Product { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    private String name; 

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "product", orphanRemoval = true) 
    private List<Price> prices = new ArrayList<>(); 

    @ManyToOne 
    @JoinFormula(
     "(SELECT id FROM price ORDER BY created_on DESC LIMIT 1)" 
    ) 
    private Price latestPrice; 

    public void setName(String name) { 
     this.name = name; 
    } 

    public List<Price> getPrices() { 
     return prices; 
    } 

    public void addPrice(BigDecimal priceValue) { 
     Price price = new Price(); 
     price.setPrice(priceValue); 
     prices.add(price); 
     price.setProduct(this); 
     latestPrice = price; 
    } 

    public Price getLatestPrice() { 
     return latestPrice; 
    } 
} 

@Entity(name = "Price") 
public class Price { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @ManyToOne 
    private Product product; 

    @Column(name = "created_on", nullable=false, updatable=false) 
    private Date createdOn; 

    private BigDecimal price; 

    public void setProduct(Product product) { 
     this.product = product; 
    } 

    public BigDecimal getPrice() { 
     return price; 
    } 

    public void setPrice(BigDecimal price) { 
     this.price = price; 
    } 

    @PrePersist 
    public void prePersist() { 
     createdOn = new Date();   
    } 
} 

這是你如何更新產品的價格:

Long id = ...; 
BigDecimal newPriceValue = ...; 

Product product = entityManager.find(Product, id); 
Price oldPrice = product.getLatestPrice();  

product.addPrice(newPriceValue); 
+0

我看見你剛纔添加的'DESC',但我想你還需要將select語句放入括號 – 2017-02-16 13:58:56

+0

當然。我意識到沒有DESC,我不會返回最新的條目,但是第一條。我也按照你的建議添加了括號。 – 2017-02-16 14:00:38