Bohdan Myslyvchuk
Bohdan Myslyvchuk

Reputation: 1817

Persist in database enum instance field value instead of enum value

for example I have such enum

public enum Season {
  WINTER(1), SPRING(10), SUMMER(50), FALL(100);
  private int expectedVisitors;
  private Season(int expectedVisitors) {
    this.expectedVisitors = expectedVisitors;
  }
  public int printExpectedVisitors() {
    return expectedVisitors;
  }
} 

and Season is a type of filed which will be stored in database.

@Column(name = "season")`
@Enumerated(EnumType.STRING)
private Season season;

But instead of value Winter I need to store int 1/10/100. What shpuld I write? And is it possible at all to do such thing?

Upvotes: 1

Views: 1196

Answers (3)

Maxwellt
Maxwellt

Reputation: 126

You can simply store season as an Integer:

@Column(name = "season")
private Integer season;

And make getter and setter with Enums:

public Season getSeason() {
    return Season.byValue(this.season);
}

public void setSeason(Season season) {
    this.season = season == null ? null : season.getValue();
}

Where Season has:

public Integer getValue() {
    return this.expectedVisitors;
}

public Season byValue(int value) {
    for (Season s : Season.values()) {
        if (s.getValue() == value) {
            return s;
        }
    }
    return null;
}

Upvotes: 1

Karuro
Karuro

Reputation: 96

For a pure JPA solution (no hibernate binding) you'll have to have access to JPA 2.1 and its new converter feature, as explained here:

https://www.thoughts-on-java.org/jpa-21-type-converter-better-way-to/

Upvotes: 0

Thomas
Thomas

Reputation: 88707

This can be done by using a custom usertype, we're doing that quite a lot.

There are many tutorials on this, e.g. here's one that a quick google search came up with: http://www.gabiaxel.com/2011/01/better-enum-mapping-with-hibernate.html

One thing that you might want to do differently though: instead of using @Type on each of your enums you could use a package-info.java in some package (we're using the package where the usertypes are defined) and annotate the package like this:

@TypeDefs( {
  @TypeDef( name = "SeasonUserType", typeClass = SeasonUserType.class, defaultForType = Season.class ) 
})
package your.package;

//a few imports here

Your entity would then just contain this:

@Column(name = "season")
private Season season;

One final thought on your enum: it looks like you want to write expectedVisitors to the database and use it to map that number back to the enum value when reading. While that would work with the usertype I'd consider that a design flaw since the number of visitors is probably not a safe identifier for a season (and it could change anyways, so it probably shouldn't be a hard coded at all).

Upvotes: 3

Related Questions