Here’s another problem that has a simple solution that took me longer than I expected to find.
I am using Hibernate 3.2.5 as my ORM. In one case, I want to map a child collection of items as an ordered List, taking advantage of the database to do my ordering.
I’m using Annotations intead of the hbm.xml format for my mappings in this project. Whenever possible, I’m using javax.persistence mappings in preference too Hibernate’s annoations.
Referring to Java Persistence with Hibernate, the mapping looks quite complicated, using Hibernate’s annotations. With some experimentation, I found a simple solution, using just the javax.persistence mappings. For simplicity, I’ll show the example annotating the Item / Bid class idea we’re used to from the Hibernate Caveat Emptor example.
package com.stevideter.domain; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.OneToMany; import javax.persistence.OrderBy; import javax.persistence.Table; import org.apache.commons.collections.CollectionUtils; @Entity @Table(name = "ITEM") public class Item implements Serializable { private static final long serialVersionUID = -7990110946186412551L; private Integer id; private List bids = new ArrayList(); @Id public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @OneToMany(mappedBy="item",cascade=CascadeType.ALL) @OrderBy("userId,date,amount") public List getBids() { return bids; } private void setBids(List bids) { this.bids = bids; } public void addBid(Bid bid) { if (CollectionUtils.isEmpty(bids)) { bids = new ArrayList();} bids.add(bid); bid.setItem(this); } public void removeBid(Bid bid) { if (CollectionUtils.isNotEmpty(bids)) { bids.remove(bid); } } } |
And for reference, here’s the mapping in the Bid with the Item as a parent:
package com.stevideter.domain; import java.io.Serializable; import java.math.BigDecimal; import java.util.Date; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; @Entity @Table(name = "BID") public class Bid implements Serializable { private static final long serialVersionUID = 8165733510722884274L; private Integer id; private Item item; private Date date; private BigDecimal amount; private Integer userId; @Id public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @ManyToOne( targetEntity = com.stevideter.domain.Item.class ) @JoinColumn(name = "itemid", nullable = false) public Item getItem() { return item; } public void setItem(Item item) { this.item = item; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public BigDecimal getAmount() { return amount; } public void setAmount(BigDecimal amount) { this.amount = amount; } public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } } |
With this mapping, the bids collection is managed by the Item, so saving the Item automatically saves the bid collection.
This example does follow the JPA standard of configuration by exception, so column names, etc., that are not explicitly called out follow the default standards.
What has been your trickiest Hibernate or javax.persistence mapping problem? How did you solve it?
–
Edited to make mapping on Bids properly bidirectional.