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
1 min

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

Share


Previous Article
MobaXterm - Enhanced SSH client for Windows
Emanuele Papa

Emanuele Papa

Android Developer

Related Posts

Flutter Padding widgets generator with Paddinger
Flutter Padding widgets generator with Paddinger
May 16, 2021
1 min

Quick Links

HomeAbout MeContact MeRSS Feed

Social Media