Enum field in JPA Entity

2020-05-21 23:59发布

问题:

I feel a little dumb asking this but I can't find any simple answer to the question.

Take this simple entity as example:

@Entity
@Table( name="clienti" )
public class Cliente implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    private String nome;

    private String cognome;

//...
}

It represents a person, so I want to add a "gender" property.

It will be "male" or "female". So what?

I can use a String, and keep in mind that "m" stands for male and "f" for female.

Or I can use a boolean "isMale", true or false.

However, I don't think in either case Hibernate purists would be happy :)

Googling a little bit I found that the best practice is using an enum.

I am a little confused on how to use it. Can you help me with an example?

回答1:

You can map your enum to a String or to an ordinal number. Mapping to String is the more portable approach as the mapping will survive changing the enumeration order.

Using your example:

@Entity
@Table( name="clienti" )
public class Cliente implements Serializable {

...
    @Enumerated(EnumType.STRING)
    private Gender gender;
...
}

The string mapping will use the simple name of the enumeration type, so you would have two possible values in the DB - 'Male' and 'Female'

public enum Gender { MALE, FEMALE }

The persistence provider takes care of the mapping, so in your code, you can continue using the Gender enum and not worry about Strings or ordinals.



回答2:

public enum Gender{ 
    MALE, FEMALE 
}



@Entity
@Table( name="clienti" )
public class Cliente implements Serializable {
...

// **1 case** - If database column type is number (integer) 
// (some time for better search performance)  -> we should use 
// EnumType.ORDINAL as @O.Badr noticed. e.g. inserted number will
// index of constant starting from 0... in our example for MALE - 0, FEMALE - 1.
// **Possible issue (advice)**: you have to add the new values at the end of
// your enum, in order to keep the ordinal correct for future values.

@Enumerated(EnumType.ORDINAL)
    private Gender gender;


// **2 case** - If database column type is character (varchar) 
// and you want to save it as String constant then ->

@Enumerated(EnumType.STRING)
    private Gender gender;

...
}

// in all case on code level you will interact with defined 
// type of Enum constant but in Database level

first case (EnumType.ORDINAL)

╔════╦══════════════╦════════╗
║ ID ║    NAME      ║ GENDER ║
╠════╬══════════════╬════════╣
║  1 ║ Jeff Atwood  ║    0   ║
║  2 ║ Geoff Dalgas ║    0   ║
║  3 ║Jarrod Jesica ║    1   ║
║  4 ║ Joel Lucy    ║    1   ║
╚════╩══════════════╩════════╝

second case (EnumType.STRING)

╔════╦══════════════╦════════╗
║ ID ║    NAME      ║ GENDER ║
╠════╬══════════════╬════════╣
║  1 ║ Jeff Atwood  ║  MALE  ║
║  2 ║ Geoff Dalgas ║  MALE  ║
║  3 ║Jarrod Jesica ║ FEMALE ║
║  4 ║ Joel Lucy    ║ FEMALE ║
╚════╩══════════════╩════════╝