如何让Hibernate扫描非实体类文件以识别@NamedNativeQueries注解
Hibernate非实体类读取@NamedNativeQueries配置解决方案
有两种可行的方案可以实现非实体类承载@NamedNativeQueries配置,同时避免将查询注解放到语义无关的实体类中:
方案1:给DTO添加@MappedSuperclass注解
这是最轻量化、语义最贴合的解决方案:
- 给你的DTO类(包括record定义的DTO)标注
@jakarta.persistence.MappedSuperclass注解,该注解的作用是标记类为JPA元数据承载类,本身不会被识别为实体,也不会生成对应数据库表 - 把
@NamedNativeQueries、@SqlResultSetMapping(你提到的@QueryResultSetMapping为笔误,正确JPA注解为该名称)注解都定义在这个DTO类上即可 - 注意要将DTO所在的包路径加入到项目的实体扫描配置中:如果是Spring Boot项目,把DTO包路径加入
@EntityScan注解的扫描范围即可,Hibernate会自动扫描该路径下所有@MappedSuperclass标注类的JPA注解
方案2:编程式手动注册命名查询
如果你不想给DTO类添加任何JPA相关注解,可以直接通过Hibernate原生API手动注册命名查询,不需要依赖注解扫描:
// 以Spring环境为例,获取EntityManagerFactory后转换为Hibernate的SessionFactoryImplementor SessionFactoryImplementor sessionFactory = entityManagerFactory.unwrap(SessionFactoryImplementor.class); // 构造原生查询定义 NamedNativeQueryDefinition queryDef = new NamedNativeQueryDefinition.Builder("yourQueryName") .setSqlString("SELECT id, name FROM your_table WHERE ...") .setResultSetMapping("yourDtoResultMapping") .build(); // 注册到Hibernate上下文 sessionFactory.getQueryEngine().getNamedObjectRepository().registerNamedNativeQueryDefinition(queryDef);
补充注意事项
- 配合
@ConstructorResult构造DTO对象时,查询返回字段的顺序、类型要和DTO的构造方法参数完全匹配,使用record定义的DTO无需手动编写无参/全参构造方法,适配性更高 - 如果需要全局调整Hibernate扫描策略,可以修改配置项
hibernate.archive.autodetection,在默认的class, hbm基础上追加mapped-superclass,确保所有元数据类都被正常扫描
内容的提问来源于stack exchange,提问作者Andrew Lazarus
相关产品推荐
相关产品推荐

