Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between @MapKey, @MapKeyColumn and @MapKeyJoinColumn in JPA and Hibernate

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!

like image 356
Chaitanya Avatar asked Aug 22 '14 04:08

Chaitanya


People also ask

When to use @mapkeyjoincolumn in hibernate?

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

What is the difference between @joincolumn and mappedby in JPA?

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.

What is the primarykeyjoincolumn annotation 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.

What is the mapkeyjoincolumn annotation?

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.


1 Answers

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; } 
like image 61
Vlad Mihalcea Avatar answered Sep 22 '22 04:09

Vlad Mihalcea