java - 如何在 Spring 使用@NamedQuery CrudRepository @Query?

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

我想在 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。

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

@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 您实际上直接绑定(bind)它们而不是将它们注释到域类。


更新 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 被注入(inject)了。

关于java - 如何在 Spring 使用@NamedQuery CrudRepository @Query?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31849392/

相关文章:

java - 在 SpringBoot 中使用 Testcontainers 进行 Spring Data Elasticsearch 集成测试

java - IllegalArgumentException 和 BeanCreationException : No property found for type error

java - Cassandra 3.5 与 Spring Data 1.4 的兼容性

java - 仅编译特定测试所需的源

java - XStream 双下划线 - 在 Java Spring Batch Application Context 中处理

java - 使用 jdbcPersistenceAdapter 重新启动嵌入式 activeMQ 代理时出现异常

java - 如何为我的 Spring MVC/Security Restful Web 服务创建自定义 JSON 401 页面?

java - 如何打印与正则表达式不匹配的文件名列表? java 8

java - 使用自己的 fxml 和 Controller 在不同场景之间切换

Java 排列赋值