Spring Boot Hibernate mapping set of enums to boolean columns

400 Views Asked by At

I have a Form enitity in Spring Boot application:

@Data
@Entity
public class Form {
    @Id
    private String caseId;
    private String leadingUnit;
    private Set<Addiction> currentAddictions;
}

Addiction is an enum:

public enum Addiction {
  Alcohol, Nicotine, Drugs
}

And I would like to map the whole form to one table in database. With the following columns: caseId, leadingUnit, currentAddictionsAlcohol, currentAddictionsNicotine and currentAddictionsDrugs. I would like the currentAddictions* columns to bo boolean indicating only if the current addiction is present in the set. I was looking at custom UserTypes but I have no idea how to do it. Is there a simple solution for this?

1

There are 1 best solutions below

2
Augusto On

This doesn't feel right (map a set to boolean columns). But here are a few options. Both options I can think require the the individual booleans to be mapped in the entity class. I want to be super clear: the correct way to map this is to have a table of addictions, and then link the tables. If later you want to add an extra addiction, this just becomes inserting a new row rather than changing the structure of the database.

  • Change the interface of your class to have a get/set for each boolean value, each set method then adds or remove the value from the Set that is not persisted. The Set can only be modified from the set boolean methods. And you probably need to use a @PostLoad lifecycle method to populate the set after loading an entity.

  • Basically the opposite: You only expose the Set with a couple of helper methods addAddiction(Addiction) and removeAddiction(Addiction). These methods internally update boolean values that are not exposed in any way. So from the interface of the class, you only have a Set.

Last option, but it's a bit of an advanced approach (so more voodoo), is to use a CompositeUserType. You can find some examples of how to create this class in here too: example 1, example 2.

My recommendation would be to stay away from the CustomUserType as things might be really complicated if, for example, you want to query all the rows with addiction = Alcohol. And please do consider mapping the addictions to their own table. Your future self (or future maintainers) will appreciate it.