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!


Posted

in

,

by

Comments

Leave a Reply

Discover more from The Full Stack Developer

Subscribe now to keep reading and get access to the full archive.

Continue reading