2013-11-26 33 views
6

我正在嘗試一些使用Glassfish4(EclipseLink)+ JavaDB的EJB3 in Action示例。所以,我有以下關係正在獲取JPA @OneToMany集合返回空

@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()返回一個空列表(大小= 0,不爲空)。爲給定項目進行投標應該做些什麼改變?

編輯:
開啓查詢日誌中評論

<property name="eclipselink.logging.level.sql" value="FINE"/> 
<property name="eclipselink.logging.parameters" value="true"/> 

我注意到,查詢列出了INSERT語句建議,但上市沒有查詢對應em.find(Item.class, itemId)後。

EDIT 2(ANSWER):
的問題是在我addBids()無狀態bean的功能,這讓我傳遞一個項目的對象。這意味着Item對象永遠不會處於持久化上下文中。正確的方法是

  1. 傳遞的itemId
  2. 找到實體管理器find()方法的項目實體。這確保了Item對象在持久化上下文中。
  3. 將出價對象添加到要出價的物品和物品
  4. 呼叫實體經理堅持()投標。

更正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; 
} 

由於@克里斯用於指出。

+0

數據庫是否包含適當的數據? –

+0

@凱文鮑爾索克斯 - 是的。說ITEM_ID = 100的商品有兩個BID_ID(5000,5001)和BID_ITEM_ID = 100的出價。 –

+2

爲什麼不看執行的SQL查詢(谷歌如何在EclipseLink中啓用查詢日誌記錄)?你確定你使用了正確的數據庫或...? –

回答

0

嘗試實例化ArrayList<Bid>並將其分配給List<Bid>聲明。

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

。請注意,我提到結果列表大小爲0,列表引用不爲空。沒有分配ArrayList,我得到空指針異常。 –

+0

@KiranMohan你的映射看起來正確,也許發佈整個實體? –

+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); } }