You can do what duckstep suggests but if you want finer grained control over where the mapping table lies you can use the following annotations.
@ElementCollection(fetch=FetchType.EAGER)
@CollectionTable(name = "FOO_TABLE", joinColumns = @JoinColumn(name = "fooId"))
@MapKeyColumn(name="mapKey")
@Column(name = "mapValue")
private Map<String, String> fooMap = new HashMap<String, String>();
This means that FOO_TABLE will have 4 columns. An ID column as the primary key, mapKey
(varchar(255)
), mapValue
(varchar(255)
), and fooId
as the foreign key.
The annotations applied to the map do the following things:
@ElementCollection(fetch=FetchType.EAGER)
- Tells Hibernate that you have a collection of elements (String's), and that these elements should always be eagerly fetched. Apply this if you never want your map to be null. On the other hand if fetching the map is an expensive query or the map is going to be particularly large and you don't always need it, set FetchType.LAZY
instead. (See here for an in depth idea of EAGER vs LAZY fetching)
@CollectionTable
- Tells Hibernate that your collection values are stored on a table. The table name is specified by the name
parameter, and the FK column is specified using the @JoinColumn
annotation.
@MapKeyColumn
- Points to the column that contains the values for the map key's.
@Column
- Points to the column that contains the values for the map value's.
You can easily change the values for @MapKeyColumn
and @Column
if you want to.
Note that if you are finding that you are not returning distinct values in the map try adding @Fetch(FetchMode.SUBSELECT)
to the collection. This indicates that Hibernate should subselect the map values rather than trying to join them to your parent.