How can I map a Map in JPA without using Hibernate's classes?
Asked
Active
Viewed 8.2k times
4 Answers
37
Although answer given by Subhendu Mahanta is correct. But @CollectionOfElements
is deprecated. You can use @ElementCollection
instead:
@ElementCollection
@JoinTable(name="ATTRIBUTE_VALUE_RANGE", joinColumns=@JoinColumn(name="ID"))
@MapKeyColumn (name="RANGE_ID")
@Column(name="VALUE")
private Map<String, String> attributeValueRange = new HashMap<String, String>();
There is no need to create a separate Entity class for the Map
field. It will be done automatically.

Jatin Sehgal
- 956
- 2
- 17
- 37
17
Does not the following work for you?
@ManyToMany(cascade = CascadeType.ALL)
Map<String,EntityType> entitytMap = new HashMap<String, EntityType>();
EntityType
could be any entity type, including a String
.

Willi Mentzel
- 27,862
- 20
- 113
- 121

Chris K
- 11,996
- 7
- 37
- 65
-
17I'm a little confused. The question was about mapping a Map
, but the "best answer" is about a Map – whiskeysierra Jan 10 '10 at 14:15. Do i miss something? -
11EntityType could be any entity type, including a String. – Chris K Jan 16 '10 at 06:41
-
3How many tables does this generate? Is there (1) one for the original class, (2) a join table (with keys for the original class and the entity type) and (3) another table for the EntityType (in the given scenario, a table with just the join table key and the mapped string)? This may be a lot of overhead, depending on the Strings saved... – RobertG Dec 18 '12 at 09:19
-
1For a solution without a join table, confer the example in http://stackoverflow.com/a/6247360/1143126 - it is buggy until hibernate 4.1.6, though. – RobertG Dec 18 '12 at 09:55
-
This shouldn't generate any join tables - he's not asking to join maps, but a Map. Not a Map of Maps. – Chris K Dec 19 '12 at 11:06
-
15@ChrisKaminski You are wrong for saying that String is entity type because it does not have Id. You know what I mean and you may know what is called entity. – Ramsharan Jul 24 '13 at 01:35
-
4For String,String mapping this will not work along. Suggesting to deselect as best answer. – Dimuthu May 21 '15 at 10:32
-
@ChrisKaminski As has already been mentioned : `String` is not a valid `Entity` – specializt Nov 11 '15 at 06:11
10
Suppose I have an entity named Book which is having a Map of chapters:
import java.io.Serializable;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import org.hibernate.annotations.CollectionOfElements;
import org.hibernate.annotations.MapKey;
@Entity
public class Book implements Serializable{
@Column(name="BOOK_ID")
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long bookId;
@CollectionOfElements(targetElement=java.lang.String.class)
@JoinTable(name="BOOK_CHAPTER",
joinColumns=@JoinColumn(name="BOOK_ID"))
@MapKey (columns=@Column(name="CHAPTER_KEY"))
@Column(name="CHAPTER")
private Map<String,String> chapters;
public Long getBookId() {
return bookId;
}
public void setBookId(Long bookId) {
this.bookId = bookId;
}
public Map<String,String> getChapters() {
return chapters;
}
public void setChapters(Map<String,String> chapters) {
this.chapters = chapters;
}
}
It works for me.

Subhendu Mahanta
- 961
- 1
- 18
- 44
-
+1. And what if i want to retrieve only the chapter 3 of all of these books? I have a similar question: http://stackoverflow.com/questions/12952625/jpa-category-language-relationship – ianaz Oct 18 '12 at 15:57
-
1@ianaz `select c from Book b join b.chapters c where key(c) = '3'` – Steve Ebersole Nov 16 '12 at 15:51
-
3Unfortunately, this requires hibernate-specific annotations. The question was for a solution without. – RobertG Dec 18 '12 at 09:23
4
A working example:
@ElementCollection(fetch=FetchType.EAGER)
@CollectionTable(name = "TABLENAME")
@MapKeyColumn(name = "KEY")
@Column(name = "VALUE")
public Map<String, String> getMap() {
return _map;
}

Yassin Hajaj
- 21,337
- 9
- 51
- 89

Francesco Taioli
- 2,687
- 1
- 19
- 34
-
for a many-to-many relationship, you'd also need `joinColumns = @JoinColumn(name="referencing_column")` within @CollectionTable and `@MapKeyJoinColumn(name="referencing_column_other_table")` – phil294 Feb 03 '17 at 00:55