Hibernate 5中java.util.Date转org.joda.time.LocalDate类型转换异常
Hibernate 5.4.33.FINAL:java.util.Date转org.joda.time.LocalDate类型转换异常(仅特定查询触发)
问题定位
你遇到的异常堆栈显示在JodaLocalDateUserType.nullSafeSet方法,但结合仅该查询报错、其他LocalDate映射正常的场景,核心问题大概率是该查询的参数绑定/结果映射逻辑与正常查询不一致,或是依赖版本、映射配置存在细节疏漏。
解决方案
1. 对齐Hibernate与Joda-Time依赖版本
Hibernate 5.4.x需搭配对应版本的hibernate-joda(或jadira-usertype-core)依赖,版本不兼容会导致类型转换逻辑混乱。确保你的依赖中,hibernate-joda版本与Hibernate核心版本一致:
<!-- Maven示例 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-joda</artifactId> <version>5.4.33.FINAL</version> </dependency>
2. 修正实体映射的UserType配置
实体映射中必须明确指定字段的类型为Joda-Time对应的Persistent实现类,不能仅写LocalDate。
- XML映射文件配置:
<property name="dateEffective" column="DATE_EFFECTIVE" type="org.jadira.usertype.dateandtime.joda.PersistentLocalDate"/>
- 注解方式配置:
@Column(name = "DATE_EFFECTIVE") @Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDate") private LocalDate dateEffective;
3. 移除手动参数转换逻辑
JodaLocalDateUserType本身支持直接将LocalDate作为查询参数绑定到数据库DATE字段,不需要手动转为java.util.Date。手动转换后,UserType接收到的参数类型与预期不符,反而触发转换异常。直接传入LocalDate参数即可:
// 错误做法:手动转Date query.setParameter("effectiveDate", new Date(localDate.toDateTimeAtStartOfDay().getMillis())); // 正确做法:直接传LocalDate query.setParameter("effectiveDate", localDate);
4. 排查查询语句特殊性
对比正常查询,检查该报错查询的差异:
- 如果是原生SQL查询:确认是否在结果映射时直接提取字段而非通过实体类,导致Hibernate未触发
JodaLocalDateUserType的转换逻辑。此时需手动处理结果集(比如将ResultSet获取的Date转为LocalDate),或改用HQL查询。 - 如果是HQL投影查询:确保投影的是实体的
dateEffective属性,而非直接写DATE_EFFECTIVE字段,否则Hibernate会直接返回java.sql.Date,无法自动转为LocalDate。
5. 全局注册Joda-Time类型(可选)
在Hibernate配置文件中全局注册Joda-Time类型,避免映射时写错全类名:
<!-- hibernate.cfg.xml --> <typedef name="localDate" class="org.jadira.usertype.dateandtime.joda.PersistentLocalDate"/>
之后映射文件中可简化为:
<property name="dateEffective" column="DATE_EFFECTIVE" type="localDate"/>
内容的提问来源于stack exchange,提问作者dynamo
相关产品推荐
相关产品推荐

