JPA原生查询返回Object数组无法转为IndieApp实体ClassCastException报错求助
问题原因
JPA 的 EntityManager.createNativeQuery() 方法执行原生SQL时,若未显式指定结果映射的实体类,默认返回值类型为 List<Object[]>,数组中每个元素对应查询结果的单个字段值,不会自动封装为目标实体对象。你代码中直接将返回值强转为 List<IndieApp> 仅能通过编译期泛型校验,运行时实际获取的元素是 Object[] 类型,调用 IndieApp 类的方法时就会触发类型转换异常。
解决方法
方案1:指定原生查询的映射实体类(推荐)
在创建原生查询时新增第二个参数,传入你要映射的 IndieApp.class,JPA 会自动将查询结果匹配封装为 IndieApp 实体对象,修改对应代码即可:
// 原代码 // List<IndieApp> indieAppList = em.createNativeQuery(sql).setMaxResults(2).getResultList(); // 修改后代码 List<IndieApp> indieAppList = em.createNativeQuery(sql, IndieApp.class).setMaxResults(2).getResultList();
注意:该方案要求
IndieApp实体的字段注解映射和indie_app表的字段完全匹配。
方案2:改用JPQL查询
如果没有必须用原生SQL的场景,可以改用JPQL写法,默认返回对应实体类型:
String jpql = "SELECT i FROM IndieApp i ORDER BY function('rand')"; List<IndieApp> indieAppList = em.createQuery(jpql, IndieApp.class).setMaxResults(2).getResultList();
额外注意点
你当前代码的循环逻辑存在问题,两次循环都取 indieAppList.get(0),会导致持久化的两条 IndieChipPickAppDetail 关联同一个应用,建议修改为:
for (int i = 0; i < 2; i++) { IndieChipPickAppDetail indieChipPickAppDetail = new IndieChipPickAppDetail(); indieChipPickAppDetail.setLikeCount(0); indieChipPickAppDetail.setIndieChipPick(newIndieChipPick); // 改为取当前下标对应的应用 indieChipPickAppDetail.setIndieApp(indieAppList.get(i)); em.persist(indieChipPickAppDetail); }
内容的提问来源于stack exchange,提问作者Lazybear
相关产品推荐
相关产品推荐

