获取JPA @OneToMany集合返回空

时间:2013-11-26 18:32:58

标签: java java-ee jpa eclipselink

我正在使用Glassfish4(EclipseLink)+ JavaDB尝试一些EJB3 in Action示例。所以我有以下关系

@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;
    }    
    ...        
}

现在提取像

这样的项目
@Override
public List<Bid> getBidsForItem(long itemId) {
    Item item = em.find(Item.class, itemId); // em -> Entity manager
    return item.getBids();
}

item.getBids()返回一个空列表(size = 0,not null)。应该对给定项目的出价进行哪些更改?

修改
  按照评论

中的建议启用查询日志记录
<property name="eclipselink.logging.level.sql" value="FINE"/>
<property name="eclipselink.logging.parameters" value="true"/>

我注意到为插入语句列出了查询,但是没有列出与em.find(Item.class, itemId)对应的查询。

编辑2(答案):
问题出在我传递Item对象的addBids()无状态bean函数中。这意味着Item对象永远不会处于持久化上下文中。正确的方法是

  1. 传递itemId
  2. 使用实体管理器find()方法查找Item实体。这可确保Item对象处于持久化上下文中。
  3. 将出价对象添加到要投标的商品和商品
  4. 在Bid上调用实体经理persist()。
  5. 更正了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指出。

2 个答案:

答案 0 :(得分:1)

试试这个: -

public class Item{
private List<Bid> bids= new ArrayList<>();
public void setBids(List<Bid> bids) {
    for (Bid bid : bids) {
        bid.setItem(this);
    }
    this.bids = bids;
}

}

在这里,您可以释放客户来建立关系。在Bid类中另外进行回合。但请确保您不会以无限的往复方法调用结束。 它是一种提供添加和删除方法的好方法。 喜欢: - public class Item{ private List<Bid> bids= new ArrayList<>(); public void addBid(Bid bid) { bid.setItem(this); this.bids.add(bids); } }

答案 1 :(得分:0)

尝试实例化ArrayList<Bid>并将其分配给List<Bid>声明。

  @OneToMany(mappedBy="item")
  protected List<Bid> bids = new ArrayList<Bid>();