How to add custom method to Spring Data JPA How to add custom method to Spring Data JPA java java

How to add custom method to Spring Data JPA


You need to create a separate interface for your custom methods:

public interface AccountRepository     extends JpaRepository<Account, Long>, AccountRepositoryCustom { ... }public interface AccountRepositoryCustom {    public void customMethod();}

and provide an implementation class for that interface:

public class AccountRepositoryImpl implements AccountRepositoryCustom {    @Autowired    @Lazy    AccountRepository accountRepository;  /* Optional - if you need it */    public void customMethod() { ... }}

See also:


In addition to axtavt's answer, don't forget you can inject Entity Manager in your custom implementation if you need it to build your queries:

public class AccountRepositoryImpl implements AccountRepositoryCustom {    @PersistenceContext    private EntityManager em;    public void customMethod() {         ...        em.createQuery(yourCriteria);        ...    }}


The accepted answer works, but has three problems:

  • It uses an undocumented Spring Data feature when naming the custom implementation as AccountRepositoryImpl. The documentation clearly states that it has to be called AccountRepositoryCustomImpl, the custom interface name plus Impl
  • You cannot use constructor injection, only @Autowired, that are considered bad practice
  • You have a circular dependency inside of the custom implementation (that's why you cannot use constructor injection).

I found a way to make it perfect, though not without using another undocumented Spring Data feature:

public interface AccountRepository extends AccountRepositoryBasic,                                           AccountRepositoryCustom { }public interface AccountRepositoryBasic extends JpaRepository<Account, Long>{    // standard Spring Data methods, like findByLogin}public interface AccountRepositoryCustom {    public void customMethod();}public class AccountRepositoryCustomImpl implements AccountRepositoryCustom {    private final AccountRepositoryBasic accountRepositoryBasic;    // constructor-based injection    public AccountRepositoryCustomImpl(        AccountRepositoryBasic accountRepositoryBasic)    {        this.accountRepositoryBasic = accountRepositoryBasic;    }    public void customMethod()     {        // we can call all basic Spring Data methods using        // accountRepositoryBasic    }}