How can I map a Map in JPA without using Hibernate's classes?
4 Answers
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.
Comments
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.
8 Comments
whiskeysierra
I'm a little confused. The question was about mapping a Map<String, String>, but the "best answer" is about a Map<String, EntityType>. Do i miss something?
Chris K
EntityType could be any entity type, including a String.
RobertG
How 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...
Ramsharan
@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.
Dimuthu
For String,String mapping this will not work along. Suggesting to deselect as best answer.
|
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.
3 Comments
ianaz
+1. And what if i want to retrieve only the chapter 3 of all of these books? I have a similar question: stackoverflow.com/questions/12952625/…
Steve Ebersole
@ianaz
select c from Book b join b.chapters c where key(c) = '3'RobertG
Unfortunately, this requires hibernate-specific annotations. The question was for a solution without.
A working example:
@ElementCollection(fetch=FetchType.EAGER)
@CollectionTable(name = "TABLENAME")
@MapKeyColumn(name = "KEY")
@Column(name = "VALUE")
public Map<String, String> getMap() {
return _map;
}
1 Comment
phil294
for a many-to-many relationship, you'd also need
joinColumns = @JoinColumn(name="referencing_column") within @CollectionTable and @MapKeyJoinColumn(name="referencing_column_other_table")