6

I have an enum in a class, mapped by Hibernate. One of the mapped fields is and enum type which has one of the following values OK, NOK or NAP. NOK or NAP works as expected, but when the field the class is set to 'OK', Hibernate fails to map and retrieve the value, which is set to null:

java.lang.IllegalArgumentException: Unknown name value for enum class     com.a.b.c.d.Class$Status: OK
    at org.hibernate.type.EnumType.nullSafeGet(EnumType.java:113)

The class has:

private Status status;

@JoinColumn(name = "STATUS")
@Enumerated(EnumType.STRING)
public Status getStatus() {
    return status;
}

public enum Status {
    OK, NOK, NAP;
}

If I change OK to OK2, it works correctly. _OK also works. As far as i'm concerned 'OK' is not a reserved name (like in this case where the guy uses new) as it compiles correctly.

Thanks!

UPDATE:

Up 'till now, what I did to solve the problem is to modify the enum and store '_OK' in the database instead of 'OK', as shown above. Not very nice solution, but it works at least.

public enum Status {
    _OK("OK"), 
    NOK("NOK"), 
    NAP("NAP");

    private String desc;

    private Status(String desc){
        this.desc = desc;
    }

    public String getDesc(){
        return desc;
    }
}

BUG REPORT:

A bug report has been filled.

5
  • 1
    Your various tests seems well thought out. It seems you've bug! Please report via hibernate's jira including your sample code. Commented Jun 21, 2011 at 22:59
  • 1
    I just answered a similar question stackoverflow.com/questions/6419783/enum-mapping-in-hibernate/… Commented Jun 22, 2011 at 2:31
  • @telm, I'm using Hibernate 3.4.0.GA and that might be the problem. But, I need to be cautious if I want to upgrade to 3.5.6 or (3.6.5, the lasted final) because that's set on a Maven pom.xml which is used in many products. So, I would have to run some tests before that. But thanks for the advice. I might do as @Bohemian told and fill a bug request. Commented Jun 22, 2011 at 15:05
  • FWIW I tried your example with DataNucleus JPA, objects persisted fine with all values, and all read back in ok. Commented Jun 22, 2011 at 15:09
  • @telm, @DataNucleus, same problem with 3.6.5.Final. I think the problem is in hibernate-annotations which didn't change from 3.4.0.GA when I changed the hibernate version on the POM.xml. Will try that before reporting. Commented Jun 22, 2011 at 18:13

3 Answers 3

10

The problem you have is that in your database you have values others than OK, NOK, NAP and when you are retrieving the records is when you are getting the exception, not when you are persisting.

From your Exception com.a.b.c.d.Class$Status: OK2 it seems as your database has that value and hence the java.lang.IllegalArgumentException: Unknown name value for enum class exception.

Check your table for invalid values, remove/correct them, and try again.

Sign up to request clarification or add additional context in comments.

7 Comments

The database has the OK2 value because I changed from OK to test with the OK2 value in the enum.
Yes and that is why it fails when you change it back to OK, because the ENUM values does not correspond with the property values. That is exactly what your exception is pointing out. If you fix the values, and get another Exception please let me know.
To rerun all the tests, I've set the the record I'm fetching to 'OK' and all the rest is still null. Also, the enum contains 'OK', 'NOK' and 'NAP'. I get the following exception: java.lang.IllegalArgumentException: Unknown name value for enum class com.a.b.c.d.Class$Status: OK at org.hibernate.type.EnumType.nullSafeGet(EnumType.java:113) Tried also to set all database records in the table to status**='OK', so no record has **status**=_null_ anymore, but I got **the same exception as above.
Why do you use @JoinColumn instead of @Column?
Well, probably a mistake. Corrected that, but the problems persists. Have you seen the updated solution, which is a quick fix but not so nice? Other than that, everything makes me believe it's a bug.
|
3

As a another workaround you can try providing an exact column definition to have a VARCHAR column:

@Column(columnDefinition = "VARCHAR(3)")
// @Column(columnDefinition = "VARCHAR2(3)") // VARCHAR2 for Oracle
@Enumerated(EnumType.STRING)
public Status getStatus() {
    return status;
}

public enum Status {
    OK, NOK, NAP;
}

Comments

2

I'm having exactly same problem after upgrading HSQLDB from 1.8 to 2.2.6. For enums Hibernate creates columns of type CHARACTER which is a fixed length column (contrary to VARCHAR). The length of it probably determined as a length of the longest enum value. INSERT/UPDATE statements are generated correctly by Hibernate, but when reading values from the table those shorter values come out appended with white spaces.

So, it seems that HSQLDB driver does not trim them. And if it should, I think the bug should be filed for HSQLDB, not Hibernate. However, if this behaviour of HSQLDB is compatible with SQL standard, then it's the Hibernate's EnumType should do trimming when reading enum values.

7 Comments

thanks for your insight. I filled the bug at Hibernate's Jira in the hope to get a clarification of what that bug might be. I'm considering filling one too at the HSQLDB Bug Tracker, but I might wait for some status change on the first, to go further on the subject.
Latest HSQLDB is compatible with the SQL standard. CHARACTER(3) means the string is padded with spaces if it's shorter. Several other databases work the same way.
Well, then is not a bug, @fredt. Thanks
@lucasarruda, did you use Hibernate to auto-generate the db schema? I am asking, since if that is Hibernate that has generated the column of a fixed length type then Hibernate should be able to read from that column without a problem, otherwise Hibernate's logic would prove inconsistent, hence containing a bug.
No, it was created by the DBA. As far as I remember (because I don't work on the place I did that code anymore) the field was defined by VARCHAR(3). And that could be the problem. But if the field where a VARCHAR(x), with x > 3, wouldn't that supposed to work too?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.