JPA MapKeyColumn Annotation Example

The following two tabs change content below.
Prasad Kharkar is a java enthusiast and always keen to explore and learn java technologies. He is SCJP,OCPWCD, OCEJPAD and aspires to be java architect.

We have learned about Entity Relationships and their mappings. Till now we have simply used lists and maps in entities. The requirement may arise to use maps in these relationships. For example, Consider employees having multiple phones assignned to them. These phones should be stored according to work and home type. How can we achieve this? This JPA MapKeyColumn Annotation Example will help understand the same.

JPA MapKeyColumn Annotation Example:

Consider following entities:

  • Employee entity has fields idEmployee, firstName,  lastName and phones
  • Phone entity has fields idPhone, phoneNumber, provider and owner.

We want to model Employee to Phone relationship as a map of which key is the phone type and its value is phone object itself. JPA MapKeyColumn Annotation Example demonstrates it using @MapKeyColumn. Let us see what javadoc says about it

Specifies the mapping for the key column of a map whose map key is a basic type. If the name element is not specified, it defaults to the concatenation of the following: the name of the referencing relationship field or property; “_”; “KEY”

We are modelling the relationship as  private Map<String, Phone> phones = new HashMap<String, Phone>(); and we will use MapKeyColumn because the key is basic type and it is not part of target object, i.e. type is not a persistent field in Phone entity. Database diagram for these two tables will be as follows.

JPA MapKeyColumn Annotation Example

Entities for JPA MapKeyColumn Annotation Example:

Let us create Employee and Phone entities corresponding to database tables:

Phone Entity

 Employee Entity

Points to notice in this JPA MapKeyColumn Annotation Example:

  • The Phone to owner i.e. Employee is ManyToOne relationship specified using  @ManyToOne private Employee owner;
  • Employee to Phone is a bidirectional OneToMany relationship specified using  private Map<String, Phone> phones = new HashMap<String, Phone>();
  • Notice the @MapKeyColumn annotation here   @MapKeyColumn(name = "phones_keys") . It is used to specify that there is a column called phones_keys in database table on the Many side of relationship i.e. Phone table. It is used to store the keys of phones field in Employee. 

Now that we have defined both entities, let us test them out.

This will create two Employee entities and two Phone entities for each of them. Database is populated with following data

Employee Table:

IDEMPLOYEE FIRST_NAME LAST_NAME
1 Prasad Kharkar
2 Sushant Pangarkar

Phone Table:

 

IDPHONE PHONENUMBER PROVIDER OWNER_IDEMPLOYEE phones_keys
1 53434524 Airtel 1 Home
2 56252314 bsnl 1 Work
3 8795656 Idea 2 Home
4 0165410254 Reliance 2 Work

I hope this JPA MapKeyColumn Annotation Example helped understand how @MapKeyColumn is used to store the key information in database when using map relationship in entities

Share Button

5 comments for “JPA MapKeyColumn Annotation Example

  1. anasuya
    July 11, 2016 at 10:38 pm

    Hi,
    Is the key not stored in database for phones table? You mentioned “we will use MapKeyColumn because the key is basic type and it is not part of target object, i.e. type is not a persistent field in Phone entity.” But I see there is a phones_keys column in phones table and the value is either home or work. Please clarify.

    Also, I understand this is a kind of ManyToOne mapping but ease of access is given to pick a particular row based on a particular column (Phones_keys). Please clarify.

    Regards,
    Anasuya

    • July 12, 2016 at 9:00 am

      Hi Anasuya, type is not persistent field of Phone entity means “there isn’t any field in Phone object which represents type. We have only four fields, i.e. idPhone, phoneNumber, provider and owner. There is an extra column phones_key in database but that is not part of Phone object. It is simply an extra column which provides some more info.” When you say a field can be persisted, it means it has java representation as well as database representation. Having only database representation and not java representation cannot be termed as persistent. So in this case, phones_key is simply an extra column which doesn’t have representation in terms of java object.

  2. Jose Manuel
    September 14, 2016 at 3:04 pm

    Hi Prasad, congratulations for such clear and helpful articles. I’m currently facing a challenge with EclipseLink JPA involving the @MapKeyColumn annotation and the @Inheritance annotation.

    I was trying to merge the example in this article with the one in the article for JPA Joined Inheritance (http://www.thejavageek.com/2014/05/17/jpa-joined-inheritance-example/). My entities are BankAccount and Meeting, both have a collection of different types of Document entities, and those Document entities need to have the reference to the owner entity.

    I can make things work using @OneToMany and @MapKeyEnumerated in my BankAccount and Meeting entities, this creates the join tables BANKACCOUNT_DOCUMENT and MEETING_DOCUMENT. In the Document entity I use the @Inheritance(strategy = InheritanceType.JOINED) annotation which creates tables for the different types of Document, which are BANK_ACCOUNT_CREATION_DOCUMENT and MEETING_ATTENDANCE_DOCUMENT.

    Everything works fine but I don’t manage to have a reference from the Document entity to its owner entity, either BankAccount or Meeting.

    I could make it work by using @Inheritance(strategy = InheritanceType.SINGLE_TABLE) in the Document entity, but I want to avoid null values for the bankaccount_id and meeting_id foreign keys.

    I wonder if this can be achieved taking advantage of the already existing join tables BANKACCOUNT_DOCUMENT and MEETING_DOCUMENT created with the @OneToMany and @MapKeyEnumerated annotations in the owner entities.

    Maybe I’m not correctly defining my model and I have to use a different approach, that would be fine for me as long as that approach does not create null value columns in the database tables for foreign keys.

  3. a1s2m9a3
    March 21, 2017 at 6:28 pm

    Hi ,
    how can i make this relation with mysql workbench?

Leave a Reply

Your email address will not be published. Required fields are marked *