Java 获取JPA@OneToMany集合返回空

Java 获取JPA@OneToMany集合返回空,java,jakarta-ee,jpa,eclipselink,Java,Jakarta Ee,Jpa,Eclipselink,我正在尝试一些使用Glassfish4(EclipseLink)+JavaDB的示例。所以我有下面的关系 @Entity @Table(name = "ITEMS") public class Item implements Serializable { private static final long serialVersionUID = 1L; private Long itemId; ... private List<Bid> bids= n

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

@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;
    }   
}
现在,在获取类似以下内容的项目时

@Override
public List<Bid> getBidsForItem(long itemId) {
    Item item = em.find(Item.class, itemId); // em -> Entity manager
    return item.getBids();
}
我注意到为insert语句列出了查询,但没有列出与
em.find(Item.class,itemId)
对应的查询

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

  • 传递itemId
  • 使用实体管理器find()方法查找项实体。这确保了项对象位于持久性上下文中
  • 将投标对象添加到项目中,并将项目添加到投标中
  • 在出价时调用实体管理器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指出。

    尝试实例化
    数组列表
    ,并将其分配给
    列表
    声明

      @OneToMany(mappedBy="item")
      protected List<Bid> bids = new ArrayList<Bid>();
    
    @OneToMany(mappedBy=“item”)
    受保护的列表出价=新的ArrayList();
    
    试试这个:-

    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;
    }
    
    公共类项目{
    私有列表出价=新的ArrayList();
    公共招标编号(投标清单){
    用于(投标:投标){
    bid.setItem(本);
    }
    此参数为:投标=投标;
    }
    
    }

    在这里,您可以释放客户来建立关系。在投标课上也要反过来做。但请确保不会以无限的来回方法调用结束。 这是一个提供添加和删除方法的好方法。 类似:-
    公共类项目{
    私有列表出价=新的ArrayList();
    公开无效投标(投标){
    bid.setItem(本);
    本.投标.增加(投标);
    }
    
    }

    数据库是否包含适当的数据?@Kevin Bowersox-是。假设Item_ID=100的项目有两个BID_ID(50005001)和BID_Item_ID=100的出价。为什么不查看执行的SQL查询(google如何在EclipseLink中启用查询日志)?是否确实使用了正确的数据库…?通过调用em.Refresh(Item);,刷新项目;。如果它有出价,请确保你保持双向关系的双方。每次向出价中添加项目时,必须将出价添加到项目的列表中bids@Chris使用em.refresh(item)它可以工作。但是函数List getBidsForItem()是无状态bean方法。作为另一个无状态bean方法的一部分,我正在向列表中添加出价。如何实现你的建议“每次你添加一个项目的出价,你必须添加到该项目的投标名单出价”,然后呢?它这样做。注意,我提到的结果列表大小是0,列表引用不是空的。没有分配ArrayList,我得到的是空指针异常。@KiranMohan您的映射看起来正确,可能会发布整个实体?
      @OneToMany(mappedBy="item")
      protected List<Bid> bids = new ArrayList<Bid>();
    
    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;
    }