Quarkus使用@NamedNativeQuery报错:命名查询未定义于JPA实体类
问题描述
开发Quarkus应用时,使用@NamedNativeQuery抛出PanacheQueryException,错误提示:
io.quarkus.panache.common.exception.PanacheQueryException: The named query 'MyClass.findUsingNamedNativeQuery' must be defined on your JPA entity or one of its super classes.
仓库类代码:
@ApplicationScoped public class MyClassRepository implements PanacheRepositoryBase<MyClass, UUID> { public Optional<MyClass> findUsingNamedNativeQuery(UUID classId){ return find("#MyClass.findUsingNamedNativeQuery", Parameters.with("classId",classId)).singleResultOptional(); } }
实体类代码:
@Entity @Table(name = "my_class") @NamedNativeQueries({ @NamedNativeQuery(name = "MyClass.findUsingNamedNativeQuery", query = """ SELECT mc.* FROM my_class mc WHERE mc.id = :classId """, resultClass = MyClass.class) }) public class MyClass{ ... }
明明已在JPA实体类中定义该命名查询,却仍报错。请问Quarkus中是否可使用@NamedNativeQuery,正确用法是什么?
解决方案
Quarkus完全支持@NamedNativeQuery,报错原因是调用方式错误:
- Panache中
find("#查询名")的语法仅适用于调用JPQL命名查询,不能直接用于原生SQL命名查询。
以下是两种正确的调用方式:
方式1:使用Panache原生命名查询方法
直接调用findNamedQuery方法,无需添加#前缀:
@ApplicationScoped public class MyClassRepository implements PanacheRepositoryBase<MyClass, UUID> { public Optional<MyClass> findUsingNamedNativeQuery(UUID classId){ return findNamedQuery("MyClass.findUsingNamedNativeQuery", Parameters.with("classId", classId)) .singleResultOptional(); } }
方式2:通过EntityManager调用
若需要更灵活的控制,可注入EntityManager直接创建原生命名查询:
@ApplicationScoped public class MyClassRepository implements PanacheRepositoryBase<MyClass, UUID> { @Inject EntityManager em; public Optional<MyClass> findUsingNamedNativeQuery(UUID classId){ return Optional.ofNullable( em.createNamedQuery("MyClass.findUsingNamedNativeQuery", MyClass.class) .setParameter("classId", classId) .getSingleResult() ); } }
额外注意事项:
- 确保
@NamedNativeQuery的name属性与调用时的名称完全一致,大小写敏感 - 原生SQL查询的字段需与实体类映射匹配,
SELECT mc.*可满足大部分基础映射场景,若有自定义字段映射需显式指定对应关系
内容的提问来源于stack exchange,提问作者renatompf
相关产品推荐
相关产品推荐

