Как использовать @NamedQuery весной CrudRepository @Query?
Я хочу использовать @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 ответов
посмотри документация 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. Читать документы для использования @Query, я думаю, вы также используете его неправильный.
обновление Чтобы использовать
Pageable
, по данным ответ
чтобы применить разбиение на страницы, должен быть получен второй подзапрос. Потому что подзапрос ссылается на те же поля, вам нужно убедиться, что ваш запрос использует псевдонимы для сущностей / таблиц, на которые он ссылается
это означает, что вы перепишите свой запрос
query ="select * from MyEntity me where me.age >= 18"
.
пример использовался для @Query
, но это также именованный запрос, поэтому он должен применяться и к вашему случаю. Разница только в том, что с @Query
вы фактически связываете их напрямую, а не аннотируете их к классу домена.
обновление 2
я попробовал в своем собственном приложении.
Во-первых, вы должны иметь запрос, используя псевдоним вместо * (i.e 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";
}
как будет работать. Для того, у кого аргумент pageable method вызывает его как myEntityRepository.allCustom(new PageRequest(0,20))
. Ofc, вы знаете, что myEntityRepository
вводят.