I am trying out some EJB3 in Action examples using Glassfish4 (EclipseLink) + JavaDB. So I have the below relationship
@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 fetching an Item like
@Override
public List<Bid> getBidsForItem(long itemId) {
Item item = em.find(Item.class, itemId); // em -> Entity manager
return item.getBids();
}
the item.getBids()
returns an empty list (size = 0, not null). What changes should be done to get Bids for the given Item?
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 notice that Queries are listed for insert statements but NO query is listed corresponding to em.find(Item.class, itemId)
.
EDIT 2 (ANSWER):
The problem was in my addBids() stateless bean function to which I was passing an Item object. This meant the Item Object is never in persistent context. The right way is to
Corrected addBids() method:
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 to @Chris for pointing out.
Try instantiating a ArrayList<Bid>
and assigning it to the List<Bid>
declaration.
@OneToMany(mappedBy="item")
protected List<Bid> bids = new ArrayList<Bid>();
Try this :-
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 are freeing the client to make the relationship. Do the otherway round in Bid class also. But make sure you won't end up with infinite to and fro method calls.
And its a good approach to provide an add and remove method.
like :- public class Item{
private List<Bid> bids= new ArrayList<>();
public void addBid(Bid bid) {
bid.setItem(this);
this.bids.add(bids);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With