Home > OS >  Why should we use @Enumerated in JPA?
Why should we use @Enumerated in JPA?

Time:07-21

I have an enum named difficulty and I marked it with @Entity and it has a one to one relationship with the recipe class. I ran my program in spring boot and it ran without any problem. My question is, why do we have to use @Enumerated? What's wrong with the way I went?

Enum:

@Entity
public enum Difficulty {
    EASY,MODERATE,HARD;

@OneToOne
private Recipe recipe;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

public Long getId() {
    return id;
}

}

Recipe class:

@Entity
public class Recipe {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
  
    @OneToOne
    private Difficulty difficulty;
     }

with @Enumareted:

@Entity
    public class Recipe {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private long id;
      
        @OneToOne
        @Enumerated(value=EnumType.STRING)
        private Difficulty difficulty;
         }

If we go with @Enumrated, we have to remove @Entity from Difficulty(I wrote Recipe which corrected), which I didn't write.

CodePudding user response:

Enum are not associations (although you can create a colletion of enums with @ElementCollection, but it's a different scenario), so you don't need the @OneToOne if you use @Enumerated. The mapping should be:

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

   @Enumerated(STRING)
   private Difficulty difficulty;
}

enum Difficulty {EASY,MODERATE, HARD;}

The value will be stored as a column in the table representing Recipe. A one-to-one association means that every time you save a recipe, you are also creating a new Difficulty. You are using enums, so I don't think that's what you want (are you sure your mapping actually works?).

Without using enums, a mapping that would make sense, would be:

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

   @ManyToOne
   private Difficulty difficulty;
}

@Entity
public class Difficulty {
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private long difficultyId;

   private String level;
}

or, if you want to use enum and associations:

@Entity
public class Difficulty {
   enum  Level {EASY, MEDIUM, HARD;}

   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private long difficultyId;

   @Enumerated(STRING)
   private Level level;
}

Having a different entity means that the difficulties are stored as rows in a separate table Difficulty. Because it's a many-to-one association, you can associate different recipes to the same difficulty.

It also means that Hibernate will need a join or a separate query to load the difficulty. I don't see the benefit if you are only interested in the name of the difficulty.

Ultimately, it depends on your use case and how you want the data to appear in the database. But if you can use enum and there is only one level per recipe, mapping it as a column seems a simpler solution.

  • Related