Hibernate中java.lang.ClassCastException异常问题求助
解决Hibernate原生SQL查询的ClassCastException问题
问题原因
使用Hibernate的createNativeQuery()执行原生SQL时,默认不会自动将查询结果映射为VendorPrioritizedData实体类对象,而是返回Object[]数组(数组中每个元素对应查询结果的一列)。直接将数组强转为实体类对象,就会触发java.lang.ClassCastException。
解决方案
方案1:指定原生SQL返回实体类型
如果你的原生SQL查询的是vendor_prioritized_data表的全部列,或者列名与实体类字段(或@Column指定的列名)完全匹配,可以直接让Hibernate将结果映射为实体对象:
// 方式1:创建查询时直接指定实体类 List<VendorPrioritizedData> fsFFDB = refDataRdsSession.createNativeQuery( DBQueries.GET_FTOS_FROM_BOB, VendorPrioritizedData.class ) .setParameter("investmentId", investmentId) .list(); // 方式2:通过addEntity指定实体类 List<VendorPrioritizedData> fsFFDB = refDataRdsSession.createNativeQuery(DBQueries.GET_FTOS_FROM_BOB) .addEntity(VendorPrioritizedData.class) .setParameter("investmentId", investmentId) .list(); // 后续遍历逻辑无需修改 List<LocalDate> tosstartDateList = new ArrayList<>(); for (VendorPrioritizedData tosStartDate : fsFFDB) { tosstartDateList.add(tosStartDate.getStartDate()); }
方案2:直接处理Object数组(仅需部分字段时)
如果你的SQL只查询了start_date等少数字段,没必要映射整个实体类,直接从数组中提取目标字段即可:
List<Object[]> fsFFDB = refDataRdsSession.createNativeQuery(DBQueries.GET_FTOS_FROM_BOB) .setParameter("investmentId", investmentId) .list(); List<LocalDate> tosstartDateList = new ArrayList<>(); for (Object[] result : fsFFDB) { // 假设start_date是查询结果的第一列,索引为0 LocalDate startDate = (LocalDate) result[0]; tosstartDateList.add(startDate); }
方案3:自定义结果映射(适合复杂查询)
如果SQL查询的是部分列,且需要封装为实体类对象,可以通过构造函数或@SqlResultSetMapping实现映射:
- 在
VendorPrioritizedData中添加对应构造函数:
public VendorPrioritizedData(LocalDate startDate) { this.startDate = startDate; }
- 修改查询代码指定映射规则:
List<VendorPrioritizedData> fsFFDB = refDataRdsSession.createNativeQuery(DBQueries.GET_FTOS_FROM_BOB) .addScalar("start_date", StandardBasicTypes.LOCAL_DATE) .setResultTransformer(Transformers.aliasToBean(VendorPrioritizedData.class)) .setParameter("investmentId", investmentId) .list();
注:Hibernate 5.2+版本中
Transformers.aliasToBean可能需要额外配置,也可以用@SqlResultSetMapping注解在实体类上定义映射规则,更推荐后者。
内容的提问来源于stack exchange,提问作者Pratik
相关产品推荐
相关产品推荐

