How to represent a composite key in hibernate?

Consider the below class representing a Student. It has a primary key id , a class id and a name field.

Say you want to combine the id and class id into a composite key.

You want the same student id to be used against a different class id.

package com.mapping.jsontype;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Student {

	@Id
	private Integer id;

	private Integer classId;

	private String name;

	/**
	 * @return the id
	 */
	public Integer getId() {
		return id;
	}

	/**
	 * @param id the id to set
	 */
	public void setId(Integer id) {
		this.id = id;
	}

	/**
	 * @return the classId
	 */
	public Integer getClassId() {
		return classId;
	}

	/**
	 * @param classId the classId to set
	 */
	public void setClassId(Integer classId) {
		this.classId = classId;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

}

We can achieve this in hibernate using @EmbeddedId annotation.

But first create an Embeddable class combining the two fields which represent the composite key like below:

package com.mapping.jsontype;

import java.io.Serializable;

import javax.persistence.Embeddable;

@Embeddable
public class StudentCompositeId implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private Integer id;

	private Integer classId;

	/**
	 * @return the id
	 */
	public Integer getId() {
		return id;
	}

	/**
	 * @param id the id to set
	 */
	public void setId(Integer id) {
		this.id = id;
	}

	/**
	 * @return the classId
	 */
	public Integer getClassId() {
		return classId;
	}

	/**
	 * @param classId the classId to set
	 */
	public void setClassId(Integer classId) {
		this.classId = classId;
	}



}

I have removed the id and class id fields from Student entity class and added them here.

Make sure to annotate the class with @Embeddable annotation and implement Serializable interface.

Then include a reference to this class in the Student entity class.

Here is the student class refactored:

package com.mapping.jsontype;

import javax.persistence.EmbeddedId;
import javax.persistence.Entity;

@Entity
public class Student {

	@EmbeddedId
	private StudentCompositeId compositeId;

	private String name;

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the compositeId
	 */
	public StudentCompositeId getCompositeId() {
		return compositeId;
	}

	/**
	 * @param compositeId the compositeId to set
	 */
	public void setCompositeId(StudentCompositeId compositeId) {
		this.compositeId = compositeId;
	}

}

That’s it!

Now you can start adding new student records based on the composite key.

The same student id can be used with a different class id.

One more thing to note here is that , the composite mapping works even if the underlying database does not have the composite key relationship. Say only student id is made as primary key in the database. And the class id is just another field.

Still you can treat them together as a composite key at the entity level!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s