Retrieving JPA collection @OneToMany returns empty

I am trying to use EJB3 examples in action using Glassfish4 (EclipseLink) + JavaDB. Therefore, I have a ratio below

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

Now when you select an item like

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

item.getBids() returns an empty list (size = 0, not null). What changes must be made to get bids for this product?

EDIT:
After enabling query logging as suggested in the comments

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

I noticed that the queries are listed for insert statements, but there are no queries in the list matching em.find(Item.class, itemId) .

EDIT 2 (ANSWER):
The problem was my addBids () function with no bean state to which I passed the Item object. This means that an Item is never in a constant context. The right way -

  • pass itemId
  • find the Item object with the find () method of the entity manager. This ensures that the Item object is in the save context.
  • Add a bid object to the item and item for the bid.
  • persist () call entity manager in Bid.

The addBids () method is fixed:

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

Thanks @Chris for pointing out.

+6
source share
2 answers

Try the following: -

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

}

Here you free the client to establish a relationship. Also do other things in the Bid class. But make sure you don't get endless calls to and fro. And this is a good approach to provide an add and remove method. for example: - public class Item{ private List<Bid> bids= new ArrayList<>(); public void addBid(Bid bid) { bid.setItem(this); this.bids.add(bids); } } public class Item{ private List<Bid> bids= new ArrayList<>(); public void addBid(Bid bid) { bid.setItem(this); this.bids.add(bids); } }

+1
source

Try creating an instance of ArrayList<Bid> and assign it to the List<Bid> declaration.

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

Source: https://habr.com/ru/post/958875/


All Articles