您正在尝试比较 Enum 和 String。
试试这个方法:
List<DTO> result = connector.findAll((root, query, cb) ->
cb.equal(root.get("helloEnum"), Hello.HELLO);
我将尝试提供一些解释为什么会发生这种情况。 Hibernate 使用Reflection 从数据库中获取ResultSet 到Class 签名。
观察堆栈跟踪你会看到类似的东西:
org.hibernate.query.spi.QueryParameterBindingValidator.validate(QueryParameterBindingValidator.java:54)
~[hibernate-core-5.2.16.Final.jar:5.2.16.Final] 在
org.hibernate.query.spi.QueryParameterBindingValidator.validate(QueryParameterBindingValidator.java:27)
~[hibernate-core-5.2.16.Final.jar:5.2.16.Final] 在
org.hibernate.query.internal.QueryParameterBindingImpl.validate(QueryParameterBindingImpl.java:90)
~[hibernate-core-5.2.16.Final.jar:5.2.16.Final] 在
org.hibernate.query.internal.QueryParameterBindingImpl.setBindValue(QueryParameterBindingImpl.java:55)
~[hibernate-core-5.2.16.Final.jar:5.2.16.Final] 在
org.hibernate.query.internal.AbstractProducedQuery.setParameter(AbstractProducedQuery.java:486)
~[hibernate-core-5.2.16.Final.jar:5.2.16.Final] 在
org.hibernate.query.internal.AbstractProducedQuery.setParameter(AbstractProducedQuery.java:104)
~[hibernate-core-5.2.16.Final.jar:5.2.16.Final]
Hibernate 在设置参数之前会执行一系列验证。
这是为Exception 初始化根本原因的最后一个方法:
public <P> void validate(Type paramType, Object bind, TemporalType temporalType) {
if ( bind == null || paramType == null ) {
// nothing we can check
return;
}
final Class parameterType = paramType.getReturnedClass();
if ( parameterType == null ) {
// nothing we can check
return;
}
if ( Collection.class.isInstance( bind ) && !Collection.class.isAssignableFrom( parameterType ) ) {
// we have a collection passed in where we are expecting a non-collection.
// NOTE : this can happen in Hibernate's notion of "parameter list" binding
// NOTE2 : the case of a collection value and an expected collection (if that can even happen)
// will fall through to the main check.
validateCollectionValuedParameterBinding( parameterType, (Collection) bind, temporalType );
}
else if ( bind.getClass().isArray() ) {
validateArrayValuedParameterBinding( parameterType, bind, temporalType );
}
else {
if ( !isValidBindValue( parameterType, bind, temporalType ) ) {
throw new IllegalArgumentException(
String.format(
"Parameter value [%s] did not match expected type [%s (%s)]",
bind,
parameterType.getName(),
extractName( temporalType )
)
);
}
}
}
有一堆检查的方法private static boolean isValidBindValue(Class expectedType, Object value, TemporalType temporalType)返回false,因为您的预期类型是class com.whatever.Hello,要检查的值是HELLO什么是String,但Enum类型和String是不兼容!
如果您在搜索条件中输入正确的Enum,验证将通过,因为private static boolean isValidBindValue(Class expectedType, Object value, TemporalType temporalType) 包含isInstance 检查将通过:
else if ( expectedType.isInstance( value ) ) {
return true;
}
在所有检查之后,Hibernate 从ResultSet 中提取值并构建List,在这种特殊情况下,List 的元素是使用反射获取的。