我创建了以下实体来管理持久购物车:
ShoppingCart.java:
@Entity
public class ShoppingCart {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@PrivateOwned
@OneToMany(mappedBy = "cart", cascade = CascadeType.ALL)
@OrderBy("creationTimestamp")
private List<ShoppingCartItem> items;
public ShoppingCart() {}
// Getters and setters...
}
ShoppingCartItem.java:
@Entity
@IdClass(ShoppingCartItemId.class)
public class ShoppingCartItem {
@Id
@ManyToOne
private Item item;
@Id
@ManyToOne
private ShoppingCart cart;
private int quantity;
@Column(precision = 17, scale = 2)
private BigDecimal price;
@Temporal(TemporalType.TIMESTAMP)
private Date creationTimestamp;
protected ShoppingCartItem() {}
@PrePersist
protected void prePersist() {
creationTimestamp = new Date();
}
public ShoppingCartItem(ShoppingCart cart, Item item, int quantity) {
this.cart = cart;
this.item = item;
this.quantity = quantity;
this.price = item.getPrice();
}
// Getters and setters...
}
Item.java:
@Entity
public class Item {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
private Brand brand;
private String model;
private String variant;
private String description;
@Column(precision = 17, scale = 2)
private BigDecimal price;
private int availability;
protected Item() {}
// Constructors, getters and setters...
}
当我发出以下JPQL查询时:
SELECT c FROM ShoppingCart c JOIN FETCH c.items WHERE c.id = :id
我注意到同一个ShoppingCartItem
中的所有ShoppingCart
在单个查询中按预期检索,但@ManyToOne private Item item;
字段不在联接中,而且每个ShoppingCartItem
都有一个单独的查询发出{1}}以在访问时获取该字段。
使用EclipseLink,还有一种方法可以在加入/批量获取Item
时获取ShoppingCartItem
连接吗?如何更改查询和/或代码?
答案 0 :(得分:1)
如果您使用的是EclipseLink,可以查看@BatchFetch和@JoinFetch注释。
答案 1 :(得分:0)
虽然似乎忽略了带有别名的left join fetch
,但我发现这个查询提示可以完成这项任务:
Query query = entityManager.createQuery("SELECT c FROM ShoppingCart c WHERE c.id = :id");
query.setHint("eclipselink.left-join-fetch", "c.items.item.brand");
这可能比注释方法更好,因为它可以按单个查询指定。
<强>更新强>
此提示的使用已损坏@OrderBy("creationTimestamp")
,因此ShoppingCartItem
不再按插入顺序返回。这可能是由于EclipseLink中的一个错误,但我认为它并没有真正受到太大的伤害,因为我实际上只需要在向用户显示购物车时订购商品而不是,例如,当用户登录和商品时在匿名购物车中必须转移到用户购物车。