How to add custom method to Spring Data JPA

spring data jpa custom query
crudrepository custom method
spring data rest custom repository method
spring mongodb repository custom query
failed to create query for method public abstract no property found for type
spring data jpa custom annotation
spring data jpa generic repository example
spring data jpa insert query example

I am looking into Spring Data JPA. Consider the below example where I will get all the crud and finder functionality working by default and if I want to customize a finder then that can be also done easily in the interface itself.

@Transactional(readOnly = true)
public interface AccountRepository extends JpaRepository<Account, Long> {

  @Query("<JPQ statement here>")
  List<Account> findByCustomer(Customer customer);
}

I would like to know how can I add a complete custom method with its implementation for the above AccountRepository? Since its an Interface I cannot implement the method there.

Spring Data JPA Tutorial: Adding Custom Methods to a Single , This blog entry describes how you can add custom methods into a single Spring Data JPA repository. The RepositoryFactoryBean is a component that is responsible of providing implementations for Spring Data JPA repository interfaces. Because we want to replace the default implementation (SimpleJpaRepository) with our custom implementation (BaseRepositoryImpl), we have to create a custom RepositoryFactoryBean.

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);
        ...
    }
}

Spring Data JPA Tutorial: Adding Custom Methods to All Repositories, This blog post describes how you can add custom methods into all Spring Data JPA repositories. When we want to add custom methods into a Spring Data JPA repository, the first thing that we have to do is to create an interface which declares the custom methods. However, because we want to create a method that returns a list of custom DTO objects, we have to create the returned DTO class before we can create the custom repository interface.

This is limited in usage, but for simple custom methods you can use default interface methods like:

import demo.database.Customer;
import org.springframework.data.repository.CrudRepository;

public interface CustomerService extends CrudRepository<Customer, Long> {


    default void addSomeCustomers() {
        Customer[] customers = {
            new Customer("Józef", "Nowak", "nowakJ@o2.pl", 679856885, "Rzeszów", "Podkarpackie", "35-061", "Zamknięta 12"),
            new Customer("Adrian", "Mularczyk", "adii333@wp.pl", 867569344, "Krosno", "Podkarpackie", "32-442", "Hynka 3/16"),
            new Customer("Kazimierz", "Dejna", "sobieski22@weebly.com", 996435876, "Jarosław", "Podkarpackie", "25-122", "Korotyńskiego 11"),
            new Customer("Celina", "Dykiel", "celina.dykiel39@yahoo.org", 947845734, "Żywiec", "Śląskie", "54-333", "Polna 29")
        };

        for (Customer customer : customers) {
            save(customer);
        }
    }
}

EDIT:

In this spring tutorial it is written:

Spring Data JPA also allows you to define other query methods by simply declaring their method signature.

So it is even possible to just declare method like:

Customer findByHobby(Hobby personHobby);

and if object Hobby is a property of Customer then Spring will automatically define method for you.

Spring Data – Add custom method to Repository – Mkyong.com, In this article, we will show you how to add a custom method to Spring Data JPA CrudRepository and MongoDB MongoRepository  Spring Data provides you an intelligent way to integrate your custom repository code and integrate it with the generic CRUD abstraction and query method functionality. To enrich a repository with custom functionality you first define an interface and an implementation for the custom functionality.

Add Custom Functionality to a Spring Data Repository, Take a look at how Spring Data allows us to add custom methods to a Spring Data So what we need is a native JPA query like this one:. Spring Data makes the process of working with entities a lot easier by merely defining repository interfaces. These come with a set of pre-defined methods and allow the possibility of adding custom methods in each interface. However, if we want to add a custom method that's available in all the repositories, the process is a bit more complex.

Im using the following code in order to access generated find methods from my custom implementation. Getting the implementation through the bean factory prevents circular bean creation problems.

public class MyRepositoryImpl implements MyRepositoryExtensions, BeanFactoryAware {

    private BrandRepository myRepository;

    public MyBean findOne(int first, int second) {
        return myRepository.findOne(new Id(first, second));
    }

    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        myRepository = beanFactory.getBean(MyRepository.class);
    }
}

Spring Data JPA, A practical guide to adding custom methods to all repositories in Spring Data JPA​. Just like derived queries, you can add sorting to any custom query of Spring Data JPA. For static ordering , the simplest and fastest way is to use the JPQL's ORDER BY clause inside the query. It is very much similar to what you use for the native SQL query.

Spring Data JPA, Defining Query Methods. Creating Repository Instances. Custom Implementations for Spring Data  Add Custom Functionality to a Spring Data Repository Take a look at how Spring Data allows us to add custom methods to a Spring Data Repository, complete with plenty of code examples. by

1. Working with Spring Data Repositories, It uses the configuration and code samples for the Java Persistence API (JPA) module. It allows quick query definition by method names but also custom-​tuning of If you only need sorting, simply add an org.springframework.data.​domain. Spring Data JPA Versions Prior to 2.0.4 The above solution for native queries works fine for Spring Data JPA version 2.0.4 and later. Prior to that version, when we try to execute such a query we'll receive an exception — the same one we described in the previous section on sorting.

How to Create Custom Method In JpaRepository, Therefore spring data allows us to add custom methods to a Spring Data package com.gkatzioura.springdata.jpa.persistence.entity;. As of version 1.1.0, Spring Data JPA ships with a custom CDI extension that allows using the repository abstraction in CDI environments. The extension is part of the JAR. To activate it, include the Spring Data JPA JAR on your classpath.

Comments
  • Can this custom implementation inject the actual repository, so it can use the methods defined there? Specifically, I'd like to reference various find* functions defined in the Repository interface in a higher level find implementation. Since those find*() functions don't have an implementation, I can't declare them in the Custom interface or Impl class.
  • I've followed this answer, unfortunately now Spring Data is trying to find the property "customMethod" on my "Account" object as it is trying to automatically generate a query for all methods defined on the AccountRepository. Any way to stop this?
  • @NickFoote note that the name of the class that you implement your repository should be: AccountRepositoryImpl not: AccountRepositoryCustomImpl, etc. - it's very strict naming convention.
  • @wired00 I think it does create a circular reference and I can't see how @JBCP got it working. When I try and do something similar I end up with an exception: Error creating bean with name 'accountRepositoryImpl': Bean with name 'accountRepositoryImpl' has been injected into other beans [accountRepository] in its raw version as part of a circular reference, but has eventually been wrapped.
  • Yeah, see my previous comment about it not working if you're extending QueryDslRepositorySupport You must also inject the repository via field or setter injection rather than constructor injection otherwise it won't be able to create the bean. It does seem to work but the solution feels a bit 'dirty', I'm not sure if there are any plans to improve how this works from the Spring Data team.
  • Thanks, however, I want to know how to use Pageable and Page in the custom implementation. Any inputs?
  • This worked. I want to emphasize the importance of the name of the parameter in the constructor must follow the convention in this answer (must be accountRepositoryBasic). Otherwise spring complained about there being 2 bean choices for injection into my *Impl constructor.
  • so what is the use of AccountRepository
  • @KalpeshSoni the methods from both AccountRepositoryBasic and AccountRepositoryCustom will be available via an injected AccountRepository
  • The is a typo on the query, it should be nameoffield, I don't have proper right to fix it.
  • There's a small caveat during testing. If you need it, let me know and I'll update the answer.
  • That is unfortunate, I've wasted so much time trying to find out, what I've made wrong, and finally, I understand that there is no such feature. Why would they even implement that functionality? To have less beans? To have all dao methods in one place? I could have achieved that in other ways. Does anyone know what is the goal of "adding behaviour to single repositories" feature?
  • You can expose any repository methods via REST by simply adding the @RestResource(path = "myQueryMethod") annotation to the method. The quote above is just stating that Spring doesn't know how you want it mapped (i.e. GET vs POST etc.) so it's up to you to specify it via the annotation.