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

时间:2015-08-06 07:26:46

标签: java spring spring-data spring-data-jpa

我想在@NamedQuery内使用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";
}

结果:

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!

1 个答案:

答案 0 :(得分:7)

查看Spring Data JPA的documentation - 使用JPA NamedQueries。

我建议您遵循文档中设置的约定(从配置的域类的简单名称开始,后跟以点分隔的方法名称)。剪切下划线并将查询命名为

@NamedQuery(name = "MyEntity.findAllCustom", query="...")

甚至可以更好地添加像findByAge或某事物

这样的暗示名称

要允许执行这些命名查询,您需要做的就是按如下方式指定MyEntityRepository:

public interface MyEntityRepository extends JpaRepository <MyEntity, Long> {
    List<MyEntity> findAllCustom();
}

我使用JpaRepository实现了它,正如文档所示。但是你可以尝试一个简单的CrudRepository,看看是否有效。

我认为问题在于您使用@Query的位置,并且对查询方法进行注释的查询将优先于使用@NamedQuery定义的查询。阅读the docs了解@Query用法,我认为你在哪里使用它也错了。

<小时/> 的更新 根据{{​​3}}

使用Pageable
  

要应用分页,必须派生第二个子查询。因为   子查询指的是相同的字段,你需要确保你的   查询使用它引用的实体/表的别名

这意味着您将重写您的查询 query ="select * from MyEntity me where me.age >= 18"

该示例用于@Query,但这也是一个命名查询,因此它也应该适用于您的案例。唯一的区别是使用@Query实际上直接绑定它们而不是将它们注释到域类。

更新2

我在自己的应用程序中尝试过。 首先,您应该使用别名而不是*(即me)进行查询。 其次,你使用FIND_ALL_CUSTOM的字符串不符合&#34; MyEntity.findAllCustom&#34;。

的约定。

解决方案

复制粘贴:

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