如何为Spring Data 3.4 @NativeQuery创建托管类型以访问数据?
问题分析
报错Not a managed type: interface com.whatever.NodesGoingUp的核心原因是:JPA的托管类型仅支持标注@Entity的实体类,接口无法被JPA识别为可托管的映射目标,给接口加@Entity也无意义。
解决方案
以下两种方法可解决自定义查询结果的映射问题,优先推荐第一种:
方法一:使用DTO数据类(推荐)
创建普通Kotlin数据类来接收查询结果,JPA可自动匹配列名与属性名完成映射:
// 定义DTO类,属性名需与查询返回的列名(node、depth)一致 data class NodesGoingUpDto( val node: String, val depth: Int )
修改DAO接口,在@NativeQuery中指定resultClass为该DTO类:
interface NodesGoingUpDao : JpaRepository<Tail, String> { @NativeQuery( value = "with recursive cte (select tail, 0 as depth from graph where source = :node union all ...) select tail as node, depth from cte", resultClass = NodesGoingUpDto::class ) fun getNodesGoingUp(node: String): List<NodesGoingUpDto> }
Kotlin数据类默认生成全参构造函数,JPA会自动将查询结果映射到DTO实例中。
方法二:使用Spring Data投影接口(需额外配置)
若坚持用接口作为结果载体,需通过@SqlResultSetMapping定义映射规则:
- 创建空实体类承载映射配置(也可将配置附加到已有实体类上):
@Entity @SqlResultSetMapping( name = "NodesGoingUpProjectionMapping", columns = [ ColumnResult(name = "node", type = String::class), ColumnResult(name = "depth", type = Int::class) ] ) class DummyMappingHolder
- 修改DAO接口的
@NativeQuery,指定resultSetMapping为上述映射名称:
interface NodesGoingUpDao : JpaRepository<Tail, String> { @NativeQuery( value = "with recursive cte (select tail, 0 as depth from graph where source = :node union all ...) select tail as node, depth from cte", resultSetMapping = "NodesGoingUpProjectionMapping" ) fun getNodesGoingUp(node: String): List<NodesGoingUp> }
此配置可让Spring Data将查询结果映射到你的NodesGoingUp接口实例,无需将接口设为托管类型。
内容的提问来源于stack exchange,提问作者badp
相关产品推荐
相关产品推荐

