Mapping Simple Key-Value Pairs: Collection Java - Util.Map Map Collections Map
Mapping Simple Key-Value Pairs: Collection Java - Util.Map Map Collections Map
Map
Mapping simple key-value pairs
The basic mappings are pretty simple. JPA and Hibernate allow you to
map a Collection of elements or an entity association to a
java.util.Map. The key and value of the Map can be a basic type, an
embeddable class or an entity.
You might have recognized that Collections are not supported. If you
want to map your association to a Map<YourKeyClass,
List<YourValueClass>>, you need to use a small workaround that I
show you at the end of this post.
www.thoughts-on-java.org
How to map an association as a java.util.Map
@Entity
public class Author {
@ManyToMany
@JoinTable(
name="AuthorBookGroup",
joinColumns={@JoinColumn(name="fk_author",
referencedColumnName="id")},
inverseJoinColumns={
@JoinColumn(name="fk_group",
referencedColumnName="id")})
@MapKey(name = "title")
private Map<String, BookGroup> bookGroups =
new HashMap<String, BookGroup>();
...
Working
} with Maps instead of Lists
That’s all you need to do to define the mapping. You can now use the
map in your domain model to add, retrieve or remove elements from
the association.
www.thoughts-on-java.org
How to map an association as a java.util.Map
Author a = new Author();
a.setFirstName("Thorben");
a.setLastName("Janssen");
em.persist(a);
a.getBooks().put(b.getTitle(), b);
You also have 2 options to use the association in JPQL query. You can
simply join the 2 entities and use them as a regular many-to-many
relationship.
TypedQuery<Author> q = em.createQuery(
"SELECT a FROM Author a JOIN a.books b “
+ “WHERE b.title LIKE :title", Author.class);
Or you can use the KEY function to reference the map key in your
query.
TypedQuery<Author> q = em.createQuery(
"SELECT a FROM Author a JOIN a.books b “
+ “WHERE KEY(b) LIKE :title ", Author.class);
www.thoughts-on-java.org
How to map an association as a java.util.Map
Represent a Collection of Embeddables as a
Map<EnumClass, EntityClass>
The mapping for embeddable classes is pretty similar. The main
difference is that you need to use the @ElementCollection annotation
instead of a @ManyToMany annotation.
@Entity
public class Author {
@ElementCollection
@MapKeyColumn(name = "address_type")
@MapKeyEnumerated(EnumType.STRING)
private Map<AddressType, Address>address =
new HashMap<AddressType, Address>();
...
}
www.thoughts-on-java.org
How to map an association as a java.util.Map
The mapping definition of that entity is very simple. You just need a
primary key and a one-to-many association to the Book entity. I also
introduced a title for the BookGroup which I want to use as the map
key on the Author entity.
@Entity
public class BookGroup {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", updatable = false,
nullable = false)
private Long id;
@OneToMany(mappedBy = "group")
private List<Book> books = new ArrayList<Book>();
...
}
www.thoughts-on-java.org
How to map an association as a java.util.Map
You can then model the association between the BookGroup and the
Author entity as a Map.
@Entity
public class Author {
@ManyToMany
@JoinTable(
name="AuthorBookGroup",
joinColumns={@JoinColumn(name="fk_author",
referencedColumnName="id")},
inverseJoinColumns={
@JoinColumn(name="fk_group",
referencedColumnName="id")})
@MapKey(name = "title")
private Map<String, BookGroup> bookGroups =
new HashMap<String, BookGroup>();
...
}
www.thoughts-on-java.org