5

I have added a custom interface with a single custom method onto a Spring Data JpaRespository, as detailed in the answer to this question;

How to add custom method to Spring Data JPA

However now I get the following error;

Caused by: org.springframework.data.mapping.PropertyReferenceException: No property customMethod found for type Account!
    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)

This appears to be because Spring Data is trying to generate a query for "customMethod" thinking its a property of "Account".

How I can stop automatic query generation for a given method?!

UPDATE My code specifically is as follows;

public interface CacheInvalidatingRepo<T> {
    public void invalidateCache(T obj);
}

@Component
public class CacheInvalidatingRepoImpl<T> implements CacheInvalidatingRepo<T> {

    @Override
    public void invalidateCache(T obj) {
        // kill the entity manager cache
    }

}

public interface VerificationRepo extends JpaRepository<Verification, BigInteger>, JpaSpecificationExecutor<Verification>, CacheInvalidatingRepo<Verification> {

}

Results in the following;

Caused by: org.springframework.data.mapping.PropertyReferenceException: No property invalidateCachefound for type Verification!
    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)
Community
  • 1
  • 1
Nick Foote
  • 2,425
  • 9
  • 36
  • 47
  • Post your code. Tell us what you're trying to achieve. – JB Nizet Jun 25 '15 at 20:20
  • Share the code for you implementation. Naming convention matters when you are using Custom Implementation with Spring Data JPA. e.g. If you have ```AccountRepository``` is the interface name then implementation class name should be ```AccountRepositoryImpl``` – Nitin Arora Jun 26 '15 at 00:34
  • I'm assuming the code from the linked question it what he used; it ought to be edited into this question. Voting to "Leave Open" though. – o11c Jun 29 '15 at 04:27
  • I came up with exactly the same problems following the instructions on [how-to-add-custom-method-to-spring-data-jpa](https://stackoverflow.com/questions/11880924/how-to-add-custom-method-to-spring-data-jpa) and couldn't find a solution nor a reason. The only thing which works is a default method in the Repository interface, but it doesn't help much if an injected EntityManager or something similar is needed. I'm using Spring data in a java ee enviroment, maybe this problem doesn't show up when using Spring Boot. – Meini Jun 05 '19 at 11:24

1 Answers1

1

TL;DR

I had a similar problem and it took me quite a while to find out. In my case it turned out that my Impl class was on different package. For example

Repository Interface.      : com.example.dao.repo.api.MyRepository
Custom Interface           : com.example.dao.repo.api.MyRepositoryCustom
Custom Implementation Class: com.example.dao.repo.impl.MyRepositoryCustomImpl

That didn't work. It was solved by moving the impl class to be below the interface package.

Repository Interface.      : com.example.dao.repo.MyRepository
Custom Interface           : com.example.dao.repo.MyRepositoryCustom
Custom Implementation Class: com.example.dao.repo.impl.MyRepositoryCustomImpl

Analysis

It seems that the way Spring Data create repository is that it will try to detect if any so-called fragment (custom implementation) present. In the case when it can detect the custom interface but not the Impl class (whether due to naming convention or package location), Spring will fallback to other method of generating the method which lead to a misleading message "No property xxx for xxx".

The Spring Data documentation actually said something about it, but it was subtle and easy to miss:

The repository infrastructure tries to autodetect custom implementation fragments by scanning for classes below the package in which it found a repository. These classes need to follow the naming convention of appending a postfix defaulting to Impl.

If you turn on debug level log for spring data and your fragment class is loaded you should be able see log like the following. Otherwise it could mean Spring fail to load the fragment. (tried with SpringBoot 2.7)

DEBUG [main] org.springframework.data.repository.config.RepositoryBeanDefinitionBuilder [RepositoryBeanDefinitionBuilder.java:196] Registering repository fragment implementation: myRepositoryCustomImpl com.example.dao.repo.impl.MyRepositoryCustomImpl
DEBUG [main] org.springframework.data.repository.config.RepositoryBeanDefinitionBuilder [RepositoryBeanDefinitionBuilder.java:218] Registering repository fragment: myRepositoryCustomImplFragment

P.S

I know this is a very old question but when I was having this problem and couldn't find answer anywhere, it was frustrating. Almost every answer was about naming convention. Hopefully this will help other who had similar problem.

reflow
  • 11
  • 2