Practical coding guides

JPA and Hibernate Composite Primary Key Mapping Example with Spring Boot and MySQL

This tutorial will walk you through the steps of mapping a JPA/Hibernate composite primary key entity example with Spring Boot, Spring Data JPA, Lombok, MySQL and Docker

What you’ll need

  • You favorite IDE
  • JDK 8+ or OpenJDK 8+
  • Maven 3+
  • MySQL Server 5+ or Docker CE 18+

Init project structure and dependencies

Project structure

├── src
│   └── main
│       ├── java
│       │   └── com
│       │       └── hellokoding
│       │           └── jpa
│       │               ├── book
│       │               │   ├── Book.java
│       │               │   └── BookRepository.java
│       │               └── JpaApplication.java
│       └── resources
│           └── application.properties
├── Dockerfile
├── docker-compose.yml
└── pom.xml

Project dependencies


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">






Define JPA Entity and Repository

Define JPA Entity

JPA Entity is defined by @Entity annotation, represent a table in your database.


package com.hellokoding.jpa.book;

import lombok.*;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;


public class Book {
    private String name;

    private Date publishedDate;

    private Date updatedDate = new Date();

    public Book(String name, Date publishedDate) {
        this.name = name;
        this.publishedDate = publishedDate;

    static class IdClass implements Serializable {
        private String name;
        private Date publishedDate;

Composite primary key is defined by a static class IdClass. It is linked to the entity by @IdClass class annotation and @Id field annotation.

Spring Data JPA Repository

Spring Data JPA contains some built-in Repository implemented some common functions to work with database such as findOne, findAll and save. All we need for this example is extends JpaRepository.


package com.hellokoding.jpa.book;

import org.springframework.data.jpa.repository.JpaRepository;

public interface BookRepository extends JpaRepository<Book, Integer>{

Define Properties and Creating Data

Application Properties




hk-mysql refers to Docker Compose service defined in the below docker-compose.yml file

spring.jpa.hibernate.ddl-auto=create allows JPA/Hibernate auto create database and table schema for you.

In practice, you may like to disable the DDL Auto feature by using spring.jpa.hibernate.ddl-auto=validate or spring.jpa.hibernate.ddl-auto=none (default). Check out this example as one of the approaches Spring Boot Flyway Example of Database Evolution

Creating data with JPA and Hibernate


package com.hellokoding.jpa;

import com.hellokoding.jpa.book.Book;
import com.hellokoding.jpa.book.BookRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import java.util.Arrays;
import java.util.Date;


class JpaApplication {
    public static void main(String[] args) {
        SpringApplication.run(JpaApplication.class, args);

    public CommandLineRunner runner(BookRepository bookRepository) {
        return r -> {
            // Create a couple of Book
            bookRepository.saveAll(Arrays.asList(new Book("Hello Koding 1", new Date()), new Book("Hello Koding 2", new Date())));

            // Fetch all
            log.info("My books: " + bookRepository.findAll());

Run the example

Run with Docker

Prepare Dockerfile for Java/Spring Boot application and docker-compose.yml for MySQL Server


FROM maven:3.5-jdk-8


version: '3'
    container_name: hk-mysql
    image: mysql/mysql-server:5.7
      MYSQL_DATABASE: test
      MYSQL_ROOT_PASSWORD: hellokoding
      MYSQL_ROOT_HOST: '%'
    - "3306:3306"
    restart: always

    build: .
    - .:/app
    - ~/.m2:/root/.m2
    working_dir: /app
    command: mvn clean spring-boot:run
    - hk-mysql

Type the below command at the project root directory, make sure your local Docker is running

docker-compose up

Access to MySQL Server docker container by issuing below bash command and key in hellokoding on Enter password:

docker exec -it hk-mysql mysql -p

Query the schema and data created by JPA/Hibernate based on your mapping

JPA Composite Primary Key

JPA Composite Primary Key

Run with JDK/OpenJDK, Maven and MySQL Server local

  • On application.properties, update data source user name + password to your local configs, update data source url hk-mysql to localhost
  • Then type this command at the project root directory mvn clean spring-boot:run

Source code


Follow HelloKoding