如何在 spring CrudRepository @Query 中使用 @NamedQuery?
How to use @NamedQuery in spring a CrudRepository @Query?
我想在 JpaRepository
中使用 @NamedQuery
。但它不起作用:
public interface MyEntityRepository extends JpaRepository<MyEntity, Long> {
@Query(name = MyEntity.FIND_ALL_CUSTOM)
List<MyEntity> findAllCustom(Pageable pageable);
}
@Entity
@NamedQuery(
name = MyEntity.FIND_ALL_CUSTOM, query = "select * from MyEntity me where me.age >= 18"
)
public class MyEntity {
public static final String FIND_ALL_CUSTOM = "findAllCustom";
}
结果:
org.springframework.data.mapping.PropertyReferenceException: No property findAllCustom found for type MyEntity!
at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:75)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:327)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:307)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:270)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:241)
at org.springframework.data.repository.query.parser.Part.<init>(Part.java:76)
at org.springframework.data.repository.query.parser.PartTree$OrPart.<init>(PartTree.java:235)
at org.springframework.data.repository.query.parser.PartTree$Predicate.buildTree(PartTree.java:373)
at org.springframework.data.repository.query.parser.PartTree$Predicate.<init>(PartTree.java:353)
at org.springframework.data.repository.query.parser.PartTree.<init>(PartTree.java:84)
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:61)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:94)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:205)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:72)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:369)
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:192)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:239)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:225)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570)
... 28 more
更新:
public interface MyEntityRepository extends JpaRepository<MyEntity, Long> {
List<MyEntity> findAllCustom(Pageable pageable);
}
@Entity
@NamedQuery(
name = "MyEntity.findAllCustom", query = "select * from MyEntity me where me.age >= 18"
)
public class MyEntity {
}
还是一样的异常:
PropertyReferenceException: No property findAllCustom found for type MyEntity!
查看 documentation 的 Spring Data JPA - 使用 JPA NamedQueries。
我建议您遵循文档中设置的约定(以配置域的简单名称 class 开头,然后是用点分隔的方法名称)。删除下划线并将查询命名为
@NamedQuery(name = "MyEntity.findAllCustom", query="...")
或者更好地添加一个暗示性名称,例如 findByAge
或 sth.
要允许执行这些命名查询,您只需按如下方式指定 MyEntityRepository:
public interface MyEntityRepository extends JpaRepository <MyEntity, Long> {
List<MyEntity> findAllCustom();
}
我用 JpaRepository
实现了它,如文档所示。但是您可以尝试使用简单的 CrudRepository
看看是否可行。
我认为问题出在您使用 @Query
的地方,并且对查询方法注释的查询将优先于使用 @NamedQuery 定义的查询。阅读the docs了解@Query的用法,我想你哪里也用错了。
更新
要使用Pageable
,根据this answer
to apply pagination, a second subquery must be derived. Because the
subquery is referring to the same fields, you need to ensure that your
query uses aliases for the entities/tables it refers to
这意味着您将像这样重写您的查询
query ="select * from MyEntity me where me.age >= 18"
.
该示例用于 @Query
,但这也是一个命名查询,因此它也应该适用于您的情况。唯一的区别是,对于 @Query
,您实际上是直接绑定它们,而不是将它们注释到域 class。
更新 2
我在自己的应用程序中尝试过。
首先,您应该使用别名而不是 *(即 me
)进行查询。
其次,您使用的字符串 FIND_ALL_CUSTOM
不遵循 "MyEntity.findAllCustom".
的约定
解决方案
复制粘贴:
public interface MyEntityRepository extends JpaRepository<MyEntity, Long> {
List<MyEntity> findAllCustom(Pageable pageable);
List<MyEntity> findAllCustom();
}
@Entity
@NamedQuery(
name = MyEntity.FIND_ALL_CUSTOM, query = "select me from MyEntity me where me.age >= 18"
)
public class MyEntity {
public static final String FIND_ALL_CUSTOM = "MyEntity.findAllCustom";
}
两者都可以。对于带有可分页方法参数的方法,将其称为 myEntityRepository.allCustom(new PageRequest(0,20))
。 Ofc,你知道注入了myEntityRepository
。
我想在 JpaRepository
中使用 @NamedQuery
。但它不起作用:
public interface MyEntityRepository extends JpaRepository<MyEntity, Long> {
@Query(name = MyEntity.FIND_ALL_CUSTOM)
List<MyEntity> findAllCustom(Pageable pageable);
}
@Entity
@NamedQuery(
name = MyEntity.FIND_ALL_CUSTOM, query = "select * from MyEntity me where me.age >= 18"
)
public class MyEntity {
public static final String FIND_ALL_CUSTOM = "findAllCustom";
}
结果:
org.springframework.data.mapping.PropertyReferenceException: No property findAllCustom found for type MyEntity!
at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:75)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:327)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:307)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:270)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:241)
at org.springframework.data.repository.query.parser.Part.<init>(Part.java:76)
at org.springframework.data.repository.query.parser.PartTree$OrPart.<init>(PartTree.java:235)
at org.springframework.data.repository.query.parser.PartTree$Predicate.buildTree(PartTree.java:373)
at org.springframework.data.repository.query.parser.PartTree$Predicate.<init>(PartTree.java:353)
at org.springframework.data.repository.query.parser.PartTree.<init>(PartTree.java:84)
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:61)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:94)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:205)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:72)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:369)
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:192)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:239)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:225)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570)
... 28 more
更新:
public interface MyEntityRepository extends JpaRepository<MyEntity, Long> {
List<MyEntity> findAllCustom(Pageable pageable);
}
@Entity
@NamedQuery(
name = "MyEntity.findAllCustom", query = "select * from MyEntity me where me.age >= 18"
)
public class MyEntity {
}
还是一样的异常:
PropertyReferenceException: No property findAllCustom found for type MyEntity!
查看 documentation 的 Spring Data JPA - 使用 JPA NamedQueries。
我建议您遵循文档中设置的约定(以配置域的简单名称 class 开头,然后是用点分隔的方法名称)。删除下划线并将查询命名为
@NamedQuery(name = "MyEntity.findAllCustom", query="...")
或者更好地添加一个暗示性名称,例如 findByAge
或 sth.
要允许执行这些命名查询,您只需按如下方式指定 MyEntityRepository:
public interface MyEntityRepository extends JpaRepository <MyEntity, Long> {
List<MyEntity> findAllCustom();
}
我用 JpaRepository
实现了它,如文档所示。但是您可以尝试使用简单的 CrudRepository
看看是否可行。
我认为问题出在您使用 @Query
的地方,并且对查询方法注释的查询将优先于使用 @NamedQuery 定义的查询。阅读the docs了解@Query的用法,我想你哪里也用错了。
更新 要使用
Pageable
,根据this answer
to apply pagination, a second subquery must be derived. Because the subquery is referring to the same fields, you need to ensure that your query uses aliases for the entities/tables it refers to
这意味着您将像这样重写您的查询
query ="select * from MyEntity me where me.age >= 18"
.
该示例用于 @Query
,但这也是一个命名查询,因此它也应该适用于您的情况。唯一的区别是,对于 @Query
,您实际上是直接绑定它们,而不是将它们注释到域 class。
更新 2
我在自己的应用程序中尝试过。
首先,您应该使用别名而不是 *(即 me
)进行查询。
其次,您使用的字符串 FIND_ALL_CUSTOM
不遵循 "MyEntity.findAllCustom".
解决方案
复制粘贴:
public interface MyEntityRepository extends JpaRepository<MyEntity, Long> {
List<MyEntity> findAllCustom(Pageable pageable);
List<MyEntity> findAllCustom();
}
@Entity
@NamedQuery(
name = MyEntity.FIND_ALL_CUSTOM, query = "select me from MyEntity me where me.age >= 18"
)
public class MyEntity {
public static final String FIND_ALL_CUSTOM = "MyEntity.findAllCustom";
}
两者都可以。对于带有可分页方法参数的方法,将其称为 myEntityRepository.allCustom(new PageRequest(0,20))
。 Ofc,你知道注入了myEntityRepository
。