Java Hibernate/JPA错误-无法识别枚举中的某些字符串
我在类中有一个枚举,由Hibernate映射。其中一个映射字段是and enum type,它具有以下值之一OK、NOK或NAPNOK或NAP按预期工作,但当类的字段设置为“OK”时,Hibernate无法映射和检索设置为null的值:Java Hibernate/JPA错误-无法识别枚举中的某些字符串,java,hibernate,exception,enums,Java,Hibernate,Exception,Enums,我在类中有一个枚举,由Hibernate映射。其中一个映射字段是and enum type,它具有以下值之一OK、NOK或NAPNOK或NAP按预期工作,但当类的字段设置为“OK”时,Hibernate无法映射和检索设置为null的值: java.lang.IllegalArgumentException: Unknown name value for enum class com.a.b.c.d.Class$Status: OK at org.hibernate.type.En
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)
该班有:
private Status status;
@JoinColumn(name = "STATUS")
@Enumerated(EnumType.STRING)
public Status getStatus() {
return status;
}
public enum Status {
OK, NOK, NAP;
}
如果我将OK更改为OK2,它将正常工作\u OK也可以。
就我而言,“OK”不是一个保留名称(就像这个家伙的例子),因为它编译正确
谢谢
更新:
到目前为止,我所做的是修改枚举并在数据库中存储“\u OK”而不是“OK”,如上图所示。这不是一个很好的解决方案,但至少它是有效的
public enum Status {
_OK("OK"),
NOK("NOK"),
NAP("NAP");
private String desc;
private Status(String desc){
this.desc = desc;
}
public String getDesc(){
return desc;
}
}
错误报告:
A 您遇到的问题是,在数据库中,您的值不是OK、NOK、NAP,当您检索记录时,是在获取异常时,而不是在持久化时 从Exception
com.a.b.c.d.Class$Status:OK2
中,您的数据库似乎具有该值,因此出现了java.lang.IllegalArgumentException:enum类的未知名称值
Exception
检查表中的无效值,删除/更正它们,然后重试。将HSQLDB从1.8升级到2.2.6后,我遇到了完全相同的问题。对于枚举,Hibernate创建CHARACTER类型的列,该列是固定长度的列(与VARCHAR相反)。它的长度可能被确定为最长枚举值的长度。INSERT/UPDATE语句是由Hibernate正确生成的,但是当从表中读取值时,这些较短的值会附加空格
所以,HSQLDB驱动程序似乎没有对它们进行修剪。如果应该的话,我认为这个bug应该提交给HSQLDB,而不是Hibernate。但是,如果HSQLDB的这种行为与SQL标准兼容,则在读取枚举值时,Hibernate的枚举类型应该进行修剪。作为另一种解决方法,您可以尝试提供精确的列定义以具有VARCHAR列:
@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;
}
你的各种测试似乎都经过深思熟虑。看来你有臭虫!请通过hibernate的jira报告,包括您的示例代码。我刚刚回答了一个类似的问题@telm,我使用的是hibernate 3.4.0.GA,这可能就是问题所在。但是,如果我想升级到3.5.6或(3.6.5,最后的最终版本),我需要谨慎,因为这是在许多产品中使用的Maven pom.xml上设置的。所以,在那之前我必须运行一些测试。但是谢谢你的建议。我可能会按照@Bohemian所说的去做,并填写一个bug请求。FWIW我用DataNucleus JPA试过你的例子,所有值的对象都保持良好,并且都读回ok。@telm,@DataNucleus,3.6.5.Final也有同样的问题。我认为问题在于hibernate注释,当我在POM.xml上更改hibernate版本时,它没有从3.4.0.GA更改。将在报告之前尝试此操作。数据库具有OK2值,因为我在枚举中使用OK2值从“确定”更改为“测试”。是,这就是为什么将其更改回“确定”时失败的原因,因为枚举值与属性值不对应。这正是你的例外所指出的。如果您修复了这些值,并获得另一个异常,请通知我。要重新运行所有测试,我已将正在获取的记录设置为“OK”,其余的仍然为空。此外,枚举包含“OK”、“NOK”和“NAP”。我得到了以下异常:
java.lang.IllegalArgumentException:enum类com.a.b.c.d.class$Status的未知名称值:org.hibernate.type.EnumType.nullSafeGet(EnumType.java:113)
还尝试将表中的所有数据库记录设置为状态**='OK',因此没有记录具有**状态**=\u null\u0,但是我得到了与上面相同的例外。为什么用@JoinColumn
而不是@Column
?可能是个错误。已更正,但问题仍然存在。您是否看到了更新后的解决方案,它是一个快速解决方案,但不是很好?除此之外,一切都让我相信这是一个错误。谢谢你的洞察力。我在Hibernate的Jira中填充了这个bug,希望能够澄清这个bug可能是什么。我也在考虑在HSQLDB Bug跟踪器上填写一个,但我可能会等待第一个状态的改变,以便进一步讨论这个问题。最新的HSQLDB与SQL标准兼容。字符(3)表示如果字符串较短,则用空格填充。其他几个数据库也是这样工作的。那么,这不是一个bug,@fredt。Thanks@lucasarruda,是否使用Hibernate自动生成数据库架构?我在问,因为如果是Hibernate生成了固定长度类型的列,那么Hibernate应该能够毫无问题地读取该列,否则Hibernate的逻辑将被证明不一致,因此包含错误。不,它是由DBA创建的。据我记忆所及(因为我不再在我编写代码的地方工作),该字段是由VARCHAR(3)定义的。这可能就是问题所在。但是如果一个VARCHAR(x)所在的字段,x>3,那么这不也应该起作用吗?