No property found for type... custom Spring Data repository
SpringSpring BootSpring DataSpring Problem Overview
I'm trying to implement a custom Spring repository. I have the interface:
public interface FilterRepositoryCustom {
List<User> filterBy(String role);
}
the implementation:
public class FilterRepositoryImpl implements FilterRepositoryCustom {
...
}
and the "main" repository, extending my custom repository:
public interface UserRepository extends JpaRepository<User, String>, FilterRepositoryCustom {
...
}
I'm using Spring Boot and, according to the docs:
> By default, Spring Boot will enable JPA repository support and look in > the package (and its subpackages) where @SpringBootApplication is > located.
When I run my application, I get this error:
> org.springframework.data.mapping.PropertyReferenceException: No property filterBy found for type User!
Spring Solutions
Solution 1 - Spring
The problem here is that you are creating FilterRepositoryImpl
but you are using it in UserRepository
. You need to create UserRepositoryImpl
to make this work.
Basically
public interface UserRepositoryCustom {
List<User> filterBy(String role);
}
public class UserRepositoryImpl implements UserRepositoryCustom {
...
}
public interface UserRepository extends JpaRepository<User, String>, UserRepositoryCustom {
...
}
Spring Data 2.x update
This answer was written for Spring 1.x. As Matt Forsythe pointed out, the naming expectations changed with Spring Data 2.0. The implementation changed from the-final-repository-interface-name-with-an-additional-Impl-suffix
to the-custom-interface-name-with-an-additional-Impl-suffix
.
So in this case, the name of the implementation would be: UserRepositoryCustomImpl
.
Solution 2 - Spring
Another way this error can happen if the impl class for FilterRepositoryCustom isn't picked up in your spring configuration:
@EnableJpaRepositories(basePackageClasses = {RepoPackageMarker.class, FilterRepositoryCustomImpl.class})
Solution 3 - Spring
Is it a must that the customMethod()
in the CustomRepository can only have parameters defined that are either
1.Entity class name - customMethod(User user)
,
2.Entity class attributes - customMethod(String firstName)
, here firstName is an attribute of User Entity class.
Can I not have something like customMethod(CustomCriteria criteria), the criteria class contain the various attributes that are used to construct a dynamic query.
e.g. getStatusByCriteria(CustomCriteria criteria), CustomCriteria
is a simple pojo annotated with @Component so that spring identifies it.
When I tried this I get an error:
> org.springframework.data.mapping.PropertyReferenceException: No > property criteria found for type UserRepository!
Solution 4 - Spring
I had the same problem. Please check if your packages structure looks like this
custom
impl
- FilterRepositoryCustomImpl.class
- FilterRepositoryCustom.class
Because when I try to use my custom repo it doesn't see the implementation. (implementation should be in the same package or in sub-packages for Spring to see it)
Maybe it helps somebody (ノ^∇^)
Solution 5 - Spring
for me the keys was
- @EnableJpaRepositories(repositoryBaseClass = MyRepositoryImpl.class)
- @NoRepositoryBean annotation on interface
follow the docs for your spring ver https://docs.spring.io/spring-data/data-commons/docs/2.3.4.RELEASE/reference/html/#repositories
so as result i have:
@NoRepositoryBean
public interface SliceRepository<T, ID> extends JpaRepository<T, ID> {..}
public class SliceRepositoryImpl<T, ID> extends SimpleJpaRepository<T, ID> implements SliceRepository<T, ID> {..}
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactory",
basePackages = {"com.some.servicename.repository"},
repositoryBaseClass = SliceRepositoryImpl.class
)
Solution 6 - Spring
I also had this error. It occured because I had configured elasticSearch repository with package
@EnableElasticsearchRepositories("some.package")
Next I moved MyElasticSearchRepository from package 'some.package' to another, but didn't change configuration
Solution 7 - Spring
I had the same problem in a project of mine. I solved the problem by adding a line in my pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<includes>
<include>com/my/package/entities/*.java</include>
<include>com/my/package/repositories/*.java</include>
<include>com/my/package/repositories/impl/*.java</include> <!-- add this -->
</includes>
</configuration>
</plugin>
Solution 8 - Spring
The most important part of the class name that corresponds to the fragment interface is the Impl postfix.
Solution 9 - Spring
Old way:
Entity aThing = repository.findOne(1L);
New way:
Optional<Entity> aThing = repository.findById(1L);