I want to make use of a @NamedQuery
inside a JpaRepository
. 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.
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.
To allow execution of these named queries all you need to do is to specify MyEntityRepository as follows:
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.
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 docs for the @Query usage, i think you where also using it wrong.
Pageable
, according to 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"
.
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.
Update 2
I tried in my own app. First off you should have the query using the alias instead of * (ie me
). Secondly the string you use FIND_ALL_CUSTOM
is not following the convention which is "MyEntity.findAllCustom".
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.