简体   繁体   English

如何在Spring中使用@NamedQuery一个CrudRepository @Query?

[英]How to use @NamedQuery in spring a CrudRepository @Query?

I want to make use of a @NamedQuery inside a JpaRepository . 我想在JpaRepository使用@NamedQuery But it does not work: 但它不起作用:

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!

Take a look at the documentation of Spring Data JPA - Using JPA NamedQueries. 看一下Spring Data 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或某findByAge这样的暗示名称。

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. 我用JpaRepository实现了它,正如文档所示。 But you could try with a simple CrudRepository and see if that works. 但你可以尝试一个简单的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. 我认为问题在于你使用@Query和查询注释的查询将优先于使用@NamedQuery定义的查询。 Read the docs for the @Query usage, i think you where also using it wrong. 阅读@Query用法的文档 ,我想你在哪里也错了。


Update To use the Pageable , according to this answer 更新要使用Pageable ,根据这个答案

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. 该示例用于@Query ,但这也是一个命名查询,因此它也应该适用于您的案例。 The only difference is that with @Query you actually bind them directly rather than annotating them to the domain class. 唯一的区别是使用@Query实际上直接绑定它们而不是将它们注释到域类。


Update 2 更新2

I tried in my own app. 我尝试了自己的应用程序。 First off you should have the query using the alias instead of * (ie me ). 首先,您应该使用别名而不是*(即me )进行查询。 Secondly the string you use FIND_ALL_CUSTOM is not following the convention which is "MyEntity.findAllCustom". 其次,你使用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)) . 对于具有可分页方法参数的那个,将其称为myEntityRepository.allCustom(new PageRequest(0,20)) Ofc, you know that myEntityRepository is injected. Ofc,你知道myEntityRepository是注入的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM