我正在尝试使用Glassfish4(EclipseLink)+ JavaDB来实践一些EJB3实战例子。因此,我有以下关系
@Entity
@Table(name = "ITEMS")
public class Item implements Serializable {
private static final long serialVersionUID = 1L;
private Long itemId;
...
private List<Bid> bids= new ArrayList<>();
@Id
@Column(name="ITEM_ID")
public Long getItemId() {
return itemId;
}
public void setItemId(Long itemId) {
this.itemId = itemId;
}
@OneToMany(mappedBy="item",fetch=FetchType.EAGER)
@JoinColumn(name="BID_ITEM_ID",referencedColumnName="ITEM_ID")
public List<Bid> getBids() {
return bids;
}
public void setBids(List<Bid> bids) {
this.bids = bids;
}
}
@Entity
@Table(name="BIDS")
public class Bid implements Serializable{
private static final long serialVersionUID = 1L;
...
private Item item;
...
@Id
@Column(name="BID_ID")
public Long getBidId() {
return bidId;
}
public void setBidId(Long bidId) {
this.bidId = bidId;
}
@ManyToOne
@JoinColumn(name="BID_ITEM_ID",referencedColumnName="ITEM_ID")
public Item getItem() {
return item;
}
public void setItem(Item item) {
this.item = item;
}
...
}
现在当获取类似于
Item
的内容时,@Override
public List<Bid> getBidsForItem(long itemId) {
Item item = em.find(Item.class, itemId); // em -> Entity manager
return item.getBids();
}
item.getBids()
返回一个空列表(大小为0,非null)。如何更改才能获取给定商品的竞标?
编辑:
如评论所建议,启用查询日志记录后。
<property name="eclipselink.logging.level.sql" value="FINE"/>
<property name="eclipselink.logging.parameters" value="true"/>
我注意到插入语句的查询被列出,但是没有对应于
em.find(Item.class, itemId)
的查询被列出。编辑2(答案): 问题出在我的addBids()无状态bean函数上,我向其中传递了一个Item对象。这意味着Item对象从未处于持久化上下文中。正确的方法是
1. 传递itemId 2. 使用实体管理器的find()方法找到Item实体。这确保了Item对象处于持久化上下文中。 3. 将竞价对象添加到项目中并将项目添加到竞价中 4. 在Bid上调用实体管理器persist()
修正后的addBids()方法:
public Bid addBids(Date bidDate, Double bidPrice, long itemId, String bidder) {
Item item = em.find(Item.class, itemId);
Bid bid = new Bid(bidDate, bidPrice, item, bidder);
item.getBids().add(bid);
em.persist(bid);
return bid;
}
感谢@Chris的指出。