2

I have a Enum with three values. It's being used as a property in an Entity bean.

Here's the property in the bean:

@Enumerated(EnumType.ORDINAL)
private BillingMethod billingMethod;

Here's the enum class:

public enum BillingMethod  {
    ONLINEBILL("enum.billingmethod.onlinebill"), // Should be 1, but is now 0 in the database
    PAPERBILL("enum.billingmethod.paperbill"), // Should be 2, but is now 1 in the database
    PRINT("enum.billingmethod.print"); // Should be 3, but is now 2 in the database

    private String tag;

    private BillingMethod(String tag){
        this.tag = tag;
    }

    @Override
    public String getTag() {
        return tag;
    }
}

There is a very rare, specific reason why I need those values to be 1, 2, 3. Instead of the usual 0, 1, 2 in the database.

Don't worry about the tag here, it is used to get the String presentation from a property file.

So, how can I set the ORDINAL to begin from 1 instead of 0?

Steve Waters
  • 3,348
  • 9
  • 54
  • 94
  • 1
    Please see: http://stackoverflow.com/questions/1067352/can-set-enum-start-value-in-java – Alex Dec 30 '16 at 18:57
  • @AlexR, that didn't work for me. Still saving 0 for the first value, 1 for the second, in the database. – Steve Waters Dec 30 '16 at 19:45
  • I didn't do a sufficient job of reading the question. I apologize. That is a work around that would allow you to use the assigned number instead of the ordinal value. Obviously that doesn't work for your use case. My mistake. – Alex Dec 30 '16 at 22:01
  • Look here: http://www.gabiaxel.com/2011/01/better-enum-mapping-with-hibernate.html I've tried it and it works ... – olivmir Jan 16 '18 at 11:35

2 Answers2

3

I see two options :

  1. The easiest: map an Integer for hibernate, do the decoding to an enum in the getter :

    @Column(...)
    private Integer billingMethod;
    
    public BillingMethod getBillingMethod() {
         // add here better error handling (logging additional info
         // to help diagnose array out of bound exceptions).
         return BillingMethod.values()[billingMethod - 1];
    }
    
    // add a setter doing a similar thing
    

    The issue is that searching with hql or criteria will not work without doing this same encoding / decoding. Not really great.

  2. Create a custom UserType. More info in the reference documentation

    Then map the field this way :

    @Type("com.fully.qualified.class.name.of.MyUserType")
    private BillingMethod billingMethod;
    

    (when using the fully qualified name of the user type in the @Type annotation, you don't need to register it)

    A bit more complex to implement, but will work in every situations where a standard enum mapping would have worked

Thierry
  • 5,270
  • 33
  • 39
1

I had the same problem - look here the solution, that worked for me:

Better Enum Mapping with Hibernate

The author uses Hibernate-UserTypes for this problem. I've implemented it the same way and it works!

olivmir
  • 692
  • 10
  • 29