HomeAbout MeContact Me
Using Spring Data to persist a Set of Enums in a Many-To-Many relationship
Development
Using Spring Data to persist a Set of Enums in a Many-To-Many relationship
Emanuele Papa
Emanuele Papa
August 24, 2017

Usually, when we write a Many-To-Many relationship it is between 2 entities. Sometimes, it could happen that we have an entity which has a field which is a set of enum. In this case, we need to approach the problem differently and Spring comes to help.

Let’s see an example where we have two classes: Person and Skill (e.g. swimming, running, etc).

Many-To-Many between entities example

The following code shows what the situation is when Person and Skill are both entities.

@Entity 
public class Person {
  @Id @GeneratedValue(strategy = GenerationType.IDENTITY) 
  private Long id;

  private String name;

  @ManyToMany(fetch = FetchType.LAZY) @JoinTable(name = "person_skill", joinColumns = {
    @JoinColumn(name = "person_id")
  }, inverseJoinColumns = {
    @JoinColumn(name = "skill_id")
  }) 
  private Set <Skill> skillSet;
}

@Entity 
public class Skill {
  @Id @GeneratedValue(strategy = GenerationType.IDENTITY) 
  private Long id;
  private String name;
}

To use this mapping, you would have 3 tables. You can create them with the following SQL code.

CREATE TABLE `person` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT, 
  `name` VARCHAR(45) NOT NULL, 
  PRIMARY KEY (`id`)
);

CREATE TABLE `skill` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT, 
  `name` VARCHAR(45) NOT NULL, 
  PRIMARY KEY (`id`)
);

CREATE TABLE `person_skill` (
  `person_id` BIGINT(20) NOT NULL, 
  `skill_id` BIGINT(20) NOT NULL, 
  PRIMARY KEY (`person_id`, `skill_id`), 
  INDEX `skill_fk_idx` (`skill_id` ASC), 
  CONSTRAINT `person_fk` FOREIGN KEY (`person_id`) REFERENCES `person` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, 
  CONSTRAINT `skill_fk` FOREIGN KEY (`skill_id`) REFERENCES `skill` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
);

Many-To-Many between entity and enum example

The following code shows what the situation is when Person is an entity and Skill is an enum.

@Entity 
public class Person {
  @Id @GeneratedValue(strategy = GenerationType.IDENTITY) 
  private Long id;

  private String name;

  @ElementCollection(targetClass = Skill.class) 
  @CollectionTable(name = "person_skill", joinColumns = @JoinColumn(name = "person_id")) 
  @Enumerated(EnumType.STRING) 
  @Column(name = "skill_name") 
  private Set <Skill> skillSet;
}

public enum Skill {
  RUNNING,
  SWIMMING
}

To use this mapping, you would have only 2 tables, because Skill is not an entity and would not have its own table. You can create them with the following SQL code.

CREATE TABLE `person` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT, 
  `name` VARCHAR(45) NOT NULL, 
  PRIMARY KEY (`id`)
);

CREATE TABLE `person_skill` (
  `person_id` BIGINT(20) NOT NULL, 
  `skill_name` VARCHAR(45) NOT NULL, 
  PRIMARY KEY (`person_id`, `skill_name`), 
  CONSTRAINT `person_fk` FOREIGN KEY (`person_id`) REFERENCES `person` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
);

As you can see here, you don’t have the table skill because Skill is not an entity but only an enum; you only have to create the table which represents the relationship between Person and Skill.

Furthermore, since we added the annotation @Enumerated(EnumType.STRING), Spring Data will save the name of the entity in the database (look, we put a VARCHAR column). If you prefer, you could use EnumType.ORDINAL and Spring Data will save the ordinal value of the entity (1,2,3,etc..), so change the column to accept a numeric value.

That’s it!


Tags


Previous ArticleMobaXterm - Enhanced SSH client for Windows
Emanuele Papa

Emanuele Papa

Android Developer

Related Posts

Control your Samsung Odyssey G95NC 57" PBP layouts and inputs from the desktop with G95NC Controller
Control your Samsung Odyssey G95NC 57" PBP layouts and inputs from the desktop with G95NC Controller
Emanuele Papa
October 16, 2026

Quick Links

HomeAbout MeContact MeRSS Feed

Social Media