Hibernate查询抛出ArrayList无法转换为Enum异常问题求助
这不是严格意义上的Hibernate Bug,而是Hibernate在JPQL解析阶段对集合类型参数的类型推断存在局限性:当你同时写了:attachmentTypes IS NULL和a.attachmentType IN :attachmentTypes时,Hibernate会错误地将List<AttachmentType>类型的参数推断为单个AttachmentType枚举类型,进而触发集合转枚举的类型转换异常。
除了动态构建查询外,还有以下几种修复方式:
方式一:用Spring Data JPA的SpEL表达式替代JPQL的null判断
把JPQL中的null判断替换为SpEL表达式,让Spring在查询执行前动态生成正确的JPQL片段,绕开Hibernate的类型推断问题:@Query( "SELECT a FROM AttachmentEntity a " + "WHERE (#{#projectId == null} OR a.projectId = :projectId) " + "AND (#{#attachmentTypes == null} OR a.attachmentType IN :attachmentTypes) " + "AND (#{#eventType == null} OR a.eventType = :eventType)" ) fun getAttachments( projectId: Int?, attachmentTypes: List<AttachmentType>?, eventType: EventType? ): List<AttachmentEntity>当参数为null时,对应的条件分支会被直接移除,Hibernate只会处理有效的条件,不会触发类型转换异常。
方式二:调整JPQL条件,用子查询辅助类型推断
通过子查询明确告知Hibernate参数是集合类型,修正类型推断逻辑:@Query( "SELECT a FROM AttachmentEntity a " + "WHERE (:projectId IS NULL OR a.projectId = :projectId) " + "AND (:attachmentTypes IS NULL OR a.attachmentType IN (SELECT item FROM :attachmentTypes item)) " + "AND (:eventType IS NULL OR a.eventType = :eventType)" ) fun getAttachments( projectId: Int?, @Param("attachmentTypes") attachmentTypes: List<AttachmentType>?, eventType: EventType? ): List<AttachmentEntity>通过
SELECT item FROM :attachmentTypes item的子查询,让Hibernate识别到:attachmentTypes是集合类型,从而正确处理参数类型。方式三:在代码层处理null参数,传入空集合
修改JPQL条件为检查集合是否为空,同时在方法层确保参数不会为null:@Query( "SELECT a FROM AttachmentEntity a " + "WHERE (:projectId IS NULL OR a.projectId = :projectId) " + "AND (:attachmentTypes IS EMPTY OR a.attachmentType IN :attachmentTypes) " + "AND (:eventType IS NULL OR a.eventType = :eventType)" ) fun getAttachments( projectId: Int?, attachmentTypes: List<AttachmentType> = emptyList(), eventType: EventType? ): List<AttachmentEntity>通过给
attachmentTypes设置空集合默认值,避免传入null参数,绕开Hibernate的类型推断问题。
内容的提问来源于stack exchange,提问作者Marty

