Saturday, June 27, 2009

Hibernate Annotations CollectionOfElements to create a Map

There are times is it very comfortable using Map data structure to easily get elements by some key. For example, suppose we have in our database a “user” table, and we would like easily store and retrieve user properties.

Hibernate gives a nice solution to this issue, by using the annotation @CollectionOfElements. We will see a demonstration of using this annotation with our “user” table. Suppose we have 2 tables in out database:

  • user: Contains users information. The table contains the following fields:
    • user_id
    • first_name
    • last_name
    • password
  • user_property: Stores user properties. The tables contains the following fields:
    • user_id
    • key
    • value

The structure of these 2 tables is quite simple and straight forward, therefore, we will not broaden on it.

We would like that “user_property” will be a Map containing key and value pairs, rather than being a collection in “user”. We will use @CollectionOfElements annotation in order to achieve that. This is how our User class looks like:

import org.hibernate.annotations.CollectionOfElements;
import javax.persistence.*;
import java.util.Map;
@Table(name = "user")
public class User implements Serializable {
  @Column(name = "user_id")
  private Integer userId;
  @Column(name = "first_name")
  private String firstName;
  @Column(name = "last_name")
  private String last_name;
  @Column(name = "password")
  private String password;
  @JoinTable(name = "user_property", joinColumns = @JoinColumn(name = "user_id"))
  @org.hibernate.annotations.MapKey(columns = {@Column(name = "key")})
  @Column(name = "value")
  private Map<String, String> properties;
  public Integer getUserId() {
    return userId;
  public void setUserId(Integer userId) {
    this.userId = userId;
  public String getFirstName() {
    return firstName;
  public void setFirstName(String firstName) {
    this.firstName = firstName;
  public String getLast_name() {
    return last_name;
  public void setLast_name(String last_name) {
    this.last_name = last_name;
  public String getPassword() {
    return password;
  public void setPassword(String password) {
    this.password = password;
  public Map<String, String> getProperties() {
    return properties;
  public void setProperties(Map<String, String> properties) { = properties;
Note that no class exists for “user_properties” table. In this case the @CollectionOfElements mapping acts like in @ManyToMany mapping. The link to “user_properties” table is defined by the “name” property of @JoinTable. Also pay attention to the fact the @MapKey annotation that is used here belongs to “org.hibernate.annotations” and not to the “javax.persistence” package.

You can also download this class by pressing this link.


  1. Hi Bashan.. This post really helped me to get started with my project to persist key value pair data. Unfortunately I am unable to retrieve any User info if i pass a map of key value as a hibernate criteria.

    public List getEvents(final Event entity){
    return this.hibernateTemplate.executeFind(new HibernateCallback() {

    public Object doInHibernate(Session session) {
    Criteria criteria = session.createCriteria(Event.class);
    criteria.add(Restrictions.between("startdatetime", entity.getStartdatetime(), entity.getEnddatetime()));

    Map map = new HashMap();
    map.put("key1", "value1");
    criteria.add(Restrictions.eq("properties", map.values()));
    return criteria.list();


    1. Hi Robin,
      Sorry, I wrote this long time ago, so I won't be able to assist on that issue. I hope you have already managed.