Java 如何在 Spring 中使用 @NamedQuery 和 CrudRepository @Query?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31849392/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use @NamedQuery in spring a CrudRepository @Query?
提问by membersound
I want to make use of a @NamedQuery
inside a JpaRepository
. But it does not work:
我想利用 a@NamedQuery
里面的 a JpaRepository
。但它不起作用:
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";
}
Result:
结果:
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
Update:
更新:
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 {
}
Still same exception:
还是一样的例外:
PropertyReferenceException: No property findAllCustom found for type MyEntity!
采纳答案by Laurentiu L.
Take a look at the documentationof Spring Data JPA - Using JPA NamedQueries.
看看该文档春数据JPA的-使用JPA NamedQueries。
I advise you follow the conventions set in the documentation (starting with the simple name of the configured domain class, followed by the method name separated by a dot). Cut the underscore and name the query like
我建议您遵循文档中设置的约定(从配置的域类的简单名称开始,然后是用点分隔的方法名称)。剪切下划线并将查询命名为
@NamedQuery(name = "MyEntity.findAllCustom", query="...")
or even better add a suggestive name like findByAge
or sth.
或者甚至更好地添加一个暗示性的名称,如findByAge
或 sth。
To allow execution of these named queries all you need to do is to specify MyEntityRepository as follows:
要允许执行这些命名查询,您需要做的就是指定 MyEntityRepository 如下:
public interface MyEntityRepository extends JpaRepository <MyEntity, Long> {
List<MyEntity> findAllCustom();
}
I implemented it with the JpaRepository
as the documentation exemplifies. But you could try with a simple CrudRepository
and see if that works.
我用JpaRepository
文档举例说明了它。但是你可以尝试一个简单的CrudRepository
,看看是否有效。
I think the problem was you where using @Query
and the Queries annotated to the query method will take precedence over queries defined using @NamedQuery. Read the docsfor the @Query usage, i think you where also using it wrong.
我认为问题在于您使用@Query
和注释到查询方法的查询将优先于使用@NamedQuery 定义的查询。阅读有关@Query 用法的文档,我认为您在何处使用它也是错误的。
Update更新使用
Pageable
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
要应用分页,必须导出第二个子查询。因为子查询引用相同的字段,所以您需要确保您的查询对其引用的实体/表使用别名
that means you would rewrite your query like
query ="select * from MyEntity me where me.age >= 18"
.
这意味着你会像
query ="select * from MyEntity me where me.age >= 18"
.
The example was used for @Query
, but that is also a named query so it should apply to your case as well. The only difference is that with @Query
you actually bind them directly rather than annotating them to the domain class.
该示例用于@Query
,但这也是一个命名查询,因此它也应该适用于您的情况。唯一的区别是@Query
您实际上直接绑定它们而不是将它们注释到域类。
Update 2
更新 2
I tried in my own app.
First off you should have the query using the alias instead of * (i.e me
).
Secondly the string you use FIND_ALL_CUSTOM
is not following the convention which is "MyEntity.findAllCustom".
我在自己的应用程序中尝试过。首先,您应该使用别名而不是 * (即me
)进行查询。其次,您使用的字符串FIND_ALL_CUSTOM
不遵循“MyEntity.findAllCustom”的约定。
Solution
解决方案
Copy paste this:
复制粘贴这个:
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";
}
Both will work. For the one with the pageable method argument call it as myEntityRepository.allCustom(new PageRequest(0,20))
. Ofc, you know that myEntityRepository
is injected.
两者都会起作用。对于具有 pageable 方法参数的方法,将其称为myEntityRepository.allCustom(new PageRequest(0,20))
. Ofc,你知道那myEntityRepository
是注入。