As per Hibernate documentation, there are multiple annotations available if we want to use Map as an association between our entities. The doc says:
Alternatively the map key is mapped to a dedicated column or columns. In order to customize the mapping use one of the following annotations:
@MapKeyColumn if the map key is a basic type. If you don't specify the column name, the name of the property followed by underscore followed by KEY is used (for example orders_KEY). @MapKeyEnumerated / @MapKeyTemporal if the map key type is respectively an enum or a Date. @MapKeyJoinColumn/@MapKeyJoinColumns if the map key type is another entity. @AttributeOverride/@AttributeOverrides when the map key is a embeddable object. Use key. as a prefix for your embeddable object property names. You can also use @MapKeyClass to define the type of the key if you don't use generics.
By doing some examples I am able to understand that @MapKey is just used to map the key to a property of target entity and this key is used only for fetching records. @MapKeyColumn is used to map the key to a property of target entity and this key is used to save as well as fetching records. Please let me know if this is correct?
Also please let me know when I need to use @MapKeyJoinColumn/@MapKeyJoinColumns & @MapKeyEnumerated / @MapKeyTemporal
Thanks!
In Hibernate, @MapKeyJoinColumn can be used when the key of map is an object. The key as an entity can be set by configuring @MapKeyJoinColumn as below
The @JoinColumn annotation helps us specify the column we'll use for joining an entity association or element collection. On the other hand, the mappedBy attribute is used to define the referencing side (non-owning side) of the relationship. In this quick tutorial, we'll look at the difference between @JoinColumn and mappedBy in JPA.
Below the relevant section from the JPA 2.0 specification: The PrimaryKeyJoinColumn annotation specifies a primary key column that is used as a foreign key to join to another table.
Specifies a mapping to an entity that is a map key. The map key join column is in the collection table, join table, or table of the target entity that is used to represent the map. If no MapKeyJoinColumn annotation is specified, a single join column is assumed and the default values apply.
When you use a Map
you always need to associate at least two entities. Let's say we have an Owner
entity that relates to the Car
entity (Car
has a FK to Owner
).
So, the Owner
will have a Map
of Car(s)
:
Map<X, Car>
@MapKey
The @MapKey
will give you the Car's
property used to group a Car
to its Owner
. For instance, if we have a vin
(Vehicle Identification Number) property in Car
, we could use it as the carMap
key:
@Entity public class Owner { @Id private long id; @OneToMany(mappedBy="owner") @MapKey(name = "vin") private Map<String, Car> carMap; } @Entity public class Car { @Id private long id; @ManyToOne private Owner owner; private String vin; }
@MapKeyEnumerated
The @MapKeyEnumerated
will use an Enum from Car
, like WheelDrive
:
@Entity public class Owner { @Id private long id; @OneToMany(mappedBy="owner") @MapKeyEnumerated(EnumType.STRING) private Map<WheelDrive, Car> carMap; } @Entity public class Car { @Id private long id; @ManyToOne private Owner owner; @Column(name = "wheelDrive") @Enumerated(EnumType.STRING) private WheelDrive wheelDrive; } public enum WheelDrive { 2WD, 4WD; }
This will group cars by their WheelDrive type.
@MapKeyTemporal
The @MapKeyTemporal
will use a Date
/Calendar
field for grouping, like createdOn
.
@Entity public class Owner { @Id private long id; @OneToMany(mappedBy="owner") @MapKeyTemporal(TemporalType.TIMESTAMP) private Map<Date, Car> carMap; } @Entity public class Car { @Id private long id; @ManyToOne private Owner owner; @Temporal(TemporalType.TIMESTAMP) @Column(name="created_on") private Calendar createdOn; }
@MapKeyJoinColumn
The @MapKeyJoinColumn
requires a third entity, like Manufacturer
so that you have an association from Owner
to Car
and car has also an association to a Manufacturer
, so that you can group all Owner's
Cars
by Manufacturer
:
@Entity public class Owner { @Id private long id; @OneToMany(mappedBy="owner") @MapKeyJoinColumn(name="manufacturer_id") private Map<Manufacturer, Car> carMap; } @Entity public class Car { @Id private long id; @ManyToOne private Owner owner; @ManyToOne @JoinColumn(name = "manufacturer_id") private Manufacturer manufacturer; } @Entity public class Manufacturer { @Id private long id; private String name; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With