Repository接口使用HQL构造函数报MappingException的解决方法
Spring Data Repository返回DTO时MappingException问题解决
问题现象
按照HQL构造函数查询的规范,在@Query注解中使用DTO构造函数是合法的,但直接通过Spring REST接口调用Repository的查询方法时,会抛出org.springframework.data.mapping.MappingException,错误提示为:
Couldn't find PersistentEntity for type class com.example.cameldemo.dto.MyDto!
但在Service层通过EntityManager执行相同的HQL查询时,却能正常返回List<MyDto>结果。
问题原因
Spring Data REST无法对非持久化的DTO类进行资源映射,当直接暴露Repository的REST接口并返回DTO时,框架会尝试将DTO当作持久化实体处理,从而触发映射异常。
解决方案
新增RestController作为Repository与REST响应的中间层,由Controller调用Repository的查询方法并直接返回结果,绕过Spring Data REST的实体映射逻辑。
实体类MyTable
package com.example.cameldemo.entity; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class MyTable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) public Long id; public String a; public String b; public String c; }
DTO类MyDto
package com.example.cameldemo.dto; public class MyDto { public Long id; public String c; public MyDto(Long id, String c) { this.id = id; this.c = c; } }
修改后的Repository
@RepositoryRestResource public interface MyTableRepository extends PagingAndSortingRepository<MyTable, Long> { @RestResource @Query("SELECT new com.example.cameldemo.dto.MyDto(mt.id, mt.c) FROM MyTable mt") List<MyDto> findAllWithQueryDto(); @RestResource @Query("SELECT mt.id AS id, mt.c AS c FROM MyTable mt") List<MyProjection> findAllWithQueryProjection(); }
新增Controller
@RestController public class MyController { @Autowired private MyTableRepository myTableRepository; @GetMapping("/myDtos2") public List<MyProjection> getMyDtos2() { return myTableRepository.findAllWithQueryProjection(); } @GetMapping("/myDtos3") public List<MyDto> getMyDtos3() { return myTableRepository.findAllWithQueryDto(); } }
内容的提问来源于stack exchange,提问作者u4963840
相关产品推荐
相关产品推荐

