Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I map a nested collection, Map<Key,List<Values>>, with hibernate JPA annotations?

I have a class I am not sure how to annotate properly.

My goal for Holder::data:

  • List should maintain order not by comparator but by the natural ordering of the elements in the array. (Which can be an ndx column if that is helpful.)
  • Holder will have the only reference to data, so Cascade all is probably applicable as well.

I am also open to a different design that removes the map, if that would make for a cleaner design.

@Entity
public class Holder extends DomainObject {
  private Map<Enum,List<Element>> data;
}

@Entity
public class Element extends DomainObject {
  private long valueId;
  private int otherData;
}

@Mappedsuperclass
public class DomainObject {
 // provides id
 // optimistic locking
 // create and update date
}
like image 285
Nathan Feger Avatar asked Jun 02 '09 12:06

Nathan Feger


People also ask

Which annotation in JPA is used to customize the mapping of a field property of an entity class to a column in the table?

@Column. Let's start with the @Column annotation. It is an optional annotation that enables you to customize the mapping between the entity attribute and the database column. You can use the name attribute to specify the name of the database column which the entity attribute map.

What is @ID annotation in hibernate?

The @Id annotation is inherited from javax.persistence.Id, indicating the member field below is the primary key of the current entity. Hence your Hibernate and spring framework as well as you can do some reflect works based on this annotation.

Which JPA annotation can be used to map the class field to a DB column?

The @Basic annotation is used to map a basic attribute type to a database column.

What is mapping in JPA?

The One-To-One mapping represents a single-valued association where an instance of one entity is associated with an instance of another entity. In this type of association one instance of source entity can be mapped atmost one instance of target entity.


2 Answers

I don't think it is possible with hibernate(-core) to map any collection of collections:

Collections may contain almost any other Hibernate type, including all basic types, custom types, components, and of course, references to other entities.

(from the official doc)

Notice the almost and the omission of the collection type.

A workaround: You need to introduce a new type 'in between' the collection holder and the element. This type you can map as an entity or a component and it refers the original content of the map, in this case a list.

Something like:

@Entity
public class Holder extends DomainObject {
  @OneToMany
  private Map<Enum,InBetween> inBetweens;
}

@Entity
public class InBetween extends DomainObject {
  @OneToMany
  private List<Element> elements;
}

@Entity
public class Element extends DomainObject {
  private long valueId;
  private int otherData;
}

@Mappedsuperclass
public class DomainObject {
 // provides id
 // optimistic locking
 // create and update date
}

The rest of the mapping depends on your particular situation, but is rather straightforward.

like image 166
Maarten Winkels Avatar answered Sep 25 '22 09:09

Maarten Winkels


Here is a blog about collection of collections in hibernate http://blog.xebia.com/2007/10/05/mapping-multimaps-with-hibernate/

Hope it will help. It helped me.

Regards, Anton

like image 41
Anton Avatar answered Sep 25 '22 09:09

Anton