Bri*_*ian 7 java hibernate classloader glassfish-4
我有一个列表中的枚举(例如)
enum State
{
UP,
DOWN,
RETRY
};
Run Code Online (Sandbox Code Playgroud)
我的数据库中的列是enum类型.当我尝试通过在查询中设置参数来执行Hibernate查询时setParameter("keyword", State.RETRY);,我收到错误
参数值[RETRY]与预期类型[package.name.State(n/a)]不匹配
在我的域的Glassfish 4.1 server.log中.我正在使用Hibernate 4.3.6.
在寻找对Hibernate的源代码,我看到发生了错误,因为线958-960在org.hibernate.jpa.spi.BaseQueryImpl:
private static boolean isValidBindValue(Class expectedType, Object value, TemporalType temporalType) {
if ( expectedType.isInstance( value ) ) {
return true;
}
...
return false;
}
Run Code Online (Sandbox Code Playgroud)
isValidBindValue 返回false,因此我收到消息.
由于这一行,它打印出String相应的enum值:
String.format("Parameter value [%s] did not match expected type [%s (%s)]",
bind,
parameterType.getName(),
extractName( temporalType )
)
Run Code Online (Sandbox Code Playgroud)
该bind目的是通过调用隐式转换为字符串值toString的方法Object,它表示enum State.RETRY.
那我怎么能说服Hibernate这State.RETRY是一个实例State?
看起来Hibernate已经更新为JPA 2.1规范,从2013年4月开始,这个规范更加严格:
https://github.com/hibernate/hibernate-orm/commit/84520cd6e36e9207c41528cf9311cae905a86425
该实体注释如下:
@Basic(optional = false)
@Column(name = "state")
@Enumerated(EnumType.String)
private State state;
Run Code Online (Sandbox Code Playgroud)
编辑:
我的RetryState枚举是由EarLibClassLoader.而Query由URLClassLoader EntityManager加载,而由不同的类加载器加载.
我想主要问题是您试图在数据库端使用枚举数据类型。不建议这样做,因为它通常需要专有的枚举类型,而 JPA 实现(例如 Hibernate)可能无法很好地支持该类型。有关详细信息,请参阅类似问题的答案。
此外,通过注释
@Enumerated(EnumType.String)
Run Code Online (Sandbox Code Playgroud)
您是说您明确希望将该值保存为数据库中的字符串。如果真正的列类型是某种枚举,我预计这会失败。也许 Hibernate 代码更改试图通过强制您使用varchar或整数列来防止这些问题。
可能的解决方案:
A)
使用 varchar 列@Enumerated(EnumType.String)或 int 列@Enumerated
二)
您可以尝试通过注释指定枚举列
@Basic(optional = false)
@Column(name = "state", columnDefinition = "enum('UP','DOWN','RETRY')")
@Enumerated(EnumType.String)
private State state;
Run Code Online (Sandbox Code Playgroud)
C)
您可以尝试通过 hibernate XML 映射文件指定枚举类:
<property name="type" column="type" not-null="true">
<type name="org.hibernate.type.EnumType">
<param name="enumClass">package.name.State</param>
<param name="type">12</param>
<!-- 12 is java.sql.Types.VARCHAR -->
</type>
</property>
Run Code Online (Sandbox Code Playgroud)
也可以看看:
通过将带有 JPA 注释的类和枚举类放入domain-dir/lib/applib目录中可以修复此问题。您必须将这些类放入domain-dir/lib/applib目录中的 JAR 中,然后使用 asadmin 在部署命令上指定该 jar--libraries jar1,jar2,etc。列出多个 JAR 文件时,请勿在逗号后放置空格。
另外,我有一个具有 EJB 远程接口的通用 JAR,因此我必须将 JPA 类分解到一个新的 JAR 中,并将它们也放在我的applibs目录中。然后,我将带有 EJB 远程接口的 JAR 放入我的 EAR\lib 目录中。
lib/applibs目录中的 JAR由URLClassLoader加载。EAR\lib 中的 JAR 由EARLibClassLoader加载。
| 归档时间: |
|
| 查看次数: |
17691 次 |
| 最近记录: |