Annotation Mapping for Ordered Lists in Hibernate

October 20th, 2008 by stevi | Filed under Java

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<Bid> bids = new ArrayList<Bid>();
 
  @Id
  public Integer getId() {
    return id;
  }
 
  public void setId(Integer id) {
    this.id = id;
  }
 
  @OneToMany(cascade=CascadeType.ALL)
  @JoinColumn(name="itemid")
  @OrderBy("userId,date,amount")
  public List<Bid> getBids() {
    return bids;
  }
 
  private void setBids(List<Bid> bids) {
    this.bids = bids;
  }
 
  public void addBid(Bid bid) {
    if (CollectionUtils.isEmpty(bids)) { bids = new ArrayList<Bid>();}
    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?

Related posts:

  1. Finding selected checkbox items in a JSF dataTable This is one of those problems that I couldn’t find...
  2. Why Are All My Collection Elements the Same as the Last One I Added? I’ve seen several programmers struggle with a similar question. They...
  3. SaveOrUpdate versus Merge in Hibernate We all have those problems that we encounter just infrequently...
  4. Processing Stored Procedure result sets in Spring Recently, I was using Spring’s JDBCTemplate for my Data Access...
  5. Using parent bean definitions in Spring This post on the JavaRanch Big Moose Saloon led me...

Related posts brought to you by Yet Another Related Posts Plugin.

tag_iconTags: | | | | | | |

You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

4 Responses to “Annotation Mapping for Ordered Lists in Hibernate”.

  1. Abhi :

    Thanks for this. Saved me a lot of time.

    But the mapping does not work if I add a database constraint saying that the itemid column in item table is not null. Then when I try to save an item class with associated bids I get an error saying “not-null property references a null or transient value”.

    Any pointers?

  2. Without seeing your code, my first question is have you added an ID generating strategy?

    That is one element I omitted from the example.

    For example, if you’re using MySQL or SQL Server, you can use the built in identity generation:
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    public Integer getId() {
    return id;
    }

    When using Oracle, I usually use the sequence strategy:

    @Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator=”ITEMID_SEQ”)
    public Integer getId() {
    return id;
    }

  3. Abhi :

    What I meant was the itemid column in bids table. I apologize for the typo.

  4. Abhi :

    I resolved it. Thanks.

Leave a comment.

To leave a comment, please fill in the fields below.