Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enum in Hibernate, persisting as an enum

In my MySQL database, there's the column "gender enum('male','female')"

I've created my enum "com.mydomain.myapp.enums.Gender", and in my Person entity I'm defined "Gender gender".

Now I'd want to keep the enum type in my MySQL database, but when I launch my application I get:

Wrong column type in MyApp.Person for column Gender. Found: enum, expected: integer

Why is this? This would be the equivalent as if I'd annotated my "Gender gender" with "@Enumerated(EnumType.ORDINAL)", which I haven't. EnumType seems only to be able to be either ORDINAL or STRING, so how do I specify that it should treat the field as an enum, not as an int? (not that there's much difference, but enough for it to get upset about it.)

like image 530
niklassaers Avatar asked Jan 29 '10 08:01

niklassaers


People also ask

Can enum values be persisted?

ORDINAL) annotation on the enum field, JPA will use the Enum. ordinal() value when persisting a given entity in the database. A problem arises with this kind of mapping when we need to modify our enum. If we add a new value in the middle or rearrange the enum's order, we'll break the existing data model.

How does hibernate store enums?

By default, Hibernate maps an enum to a number. It uses the ordinal value, which is the zero-based position of a value within the definition of the enum. So, the enum value that's defined first gets mapped to 0, the second one to 1 and so on.

How do I map an enum to a column in a database?

To map the Enum to a String database column type, you need to specify the EnumType. STRING value when using the @Enumerated annotation. As expected, the String representation of the Java Enum was used to populate the associated database column value.

Can enum be subclassed?

We've learned that we can't create a subclass of an existing enum. However, an interface is extensible. Therefore, we can emulate extensible enums by implementing an interface.


2 Answers

If you give Hibernate a column definition, it won't try to guess one:

@Column(columnDefinition = "enum('MALE','FEMALE')") @Enumerated(EnumType.STRING) private Gender gender; 

If you aren't relying on Hibernate to generate your schema for any reason, you don't even have to provide real values for the columnDefinition. This way, you remove an instance where you need to keep the values in sync. Just keep your Java enum and your Liquibase or SQL script in sync:

@Column(columnDefinition = "enum('DUMMY')") @Enumerated(EnumType.STRING) private ManyValuedEnum manyValuedEnum; 
like image 198
Jimmie Fulton Avatar answered Sep 28 '22 11:09

Jimmie Fulton


My understanding is that MySQL enum type is very proprietary and not well supported by Hibernate, see this comment from Gavin King (this related issue is a bit different but that's not the important part).

So, I actually think that you'll have to use your own UsereType and I'd recommend to use the Flexible solution - working version from the Java 5 EnumUserType (see Appfuse's Java 5 Enums Persistence with Hibernate for an example).

Personally, I'd just forget the idea to use MySQL enum, I'm not convinced that the "benefits" are worth it (see this answer for more details).

like image 22
Pascal Thivent Avatar answered Sep 28 '22 10:09

Pascal Thivent