Spring JPA: How to disable query creation for certain method

Viewed 524

I have a custom repository declared like below(written in Kotlin):

interface FooRepository : JpaRepository<Foo, Int> {
    fun findByFoo(foo: String): List<Foo>

    fun findByBar(bar: String): List<Foo> {
        //custom implementation
    }
}

data class Foo(var id: Int, var foo: String, var bar: String)

Both methods satisfy the naming convention of JPA repository, but I want to implement the second method (FooRepository.findByBar) on my own. How can I prevent JPA from creating a query for it?
Note that my custom implementation involves computation logic, thus the @Query annotation that allows for a custom query doesn't meet my requirement.
Besides, in the real situation, it's necessary and reasonable to do this, so don't post your answer or comment if you're trying to suggest for a "better" design pattern, like placing the implementation in the service layer, etc.

2 Answers

You can simply create another interface like 'FooRepositoryCustom' and also create a Implementation class for that (FooRepositoryCustomImpl) and do your implementation on that FooRepositoryCustomImpl class and extend the FooRepositoryCustom interface to your FooRepository interface.

FooRepositoryCustom:

public interface FooRepositoryCustom {
    fun findByBar(bar: String): List<Foo>;
}

FooRepositoryCustomImpl:

public class FooRepositoryCustomImpl implements FooRepositoryCustom {
    @Override
    public fun findByBar(bar: String): List<Foo> {
          //your implementation goes here
    }
}

FooRepository:

interface FooRepository : JpaRepository<Foo, Int>, FooRepositoryCustom {

}

Best practise: As suggested by Heshan, you can add custom interfaces to your repository interface. Your implementation will be loaded (file name with "Impl" suffix) and it will override the default methods of the same name.

Extending JpaRepository: Why do you want to extend the JpaRepository interface? If you do this, Spring will attempt to create a repository instance itself. To prevent this, annotate your repository interface with @NoRepositoryBean.

@NoRepositoryBean
public interface FooRepositoryCustom extends JpaRepository<Foo, Int> {
}

Reference: I am trying to do something similar with Spring Data Elasticsearch - override existing repository methods. I followed their documentation, see https://docs.spring.io/spring-data/elasticsearch/docs/4.1.15/reference/html/#repositories.custom-implementations

Related