39

How can I get access to the Entity Manager in the repository when using Spring Boot and Spring Data?

Otherwise, I will need to put my big query in an annotation. I would prefer to have something more clear than a long text.

dariosicily
  • 4,239
  • 2
  • 11
  • 17
robert trudel
  • 5,283
  • 17
  • 72
  • 124

2 Answers2

40

You would define a CustomRepository to handle such scenarios. Consider you have CustomerRepository which extends the default spring data JPA interface JPARepository<Customer,Long>

Create a new interface CustomCustomerRepository with a custom method signature.

public interface CustomCustomerRepository {
    public void customMethod();
}

Extend CustomerRepository interface using CustomCustomerRepository

public interface CustomerRepository extends JpaRepository<Customer, Long>, CustomCustomerRepository{

}

Create an implementation class named CustomerRepositoryImpl which implements CustomerRepository. Here you can inject the EntityManager using the @PersistentContext. Naming conventions matter here.

public class CustomCustomerRepositoryImpl implements CustomCustomerRepository {

    @PersistenceContext
    private EntityManager em;

    @Override
    public void customMethod() {
    
    }
}
Community
  • 1
  • 1
Nitin Arora
  • 2,650
  • 1
  • 26
  • 27
  • 2
    CustomerRepositoryImpl class should implement CustomCustomerRepository not CustomerRepository as only method of CustomCustomerRepository needs implementation – Nikhil Mahajan Dec 05 '16 at 09:45
  • Does this CustomCustomerRepositoryImpl work without a customMethod()? – Doc Brown Dec 11 '17 at 12:48
  • 4
    I am getting this error `No property customMethod found for type Customer` do I need to do any configuration ? – Rookie007 Jun 21 '19 at 03:55
  • 1
    If you get error "No property customMethod found for type Customer" remove annotation @PersistenceContext and inject the entityManager object via the constructor of CustomRepositoryImpl – cnmuc Jun 10 '20 at 10:18
  • @cnmuc can you elaborate on the solution you mentioned. I am facing the same issue as you mentioned. – Avik Aggarwal Oct 15 '20 at 19:12
  • 2
    @AvikAggarwal public class CustomerRepositoryImpl implements CustomCustomerRepository { private final EntityManager entityManager; public CustomerRepositoryImpl(EntityManager entityManager) { this.entityManager = entityManager; } } – cnmuc Oct 15 '20 at 19:53
  • Thanks @cnmuc. I had implemented that but now I face `No query defined for that name`. Any idea about this? Please note I am using a query to transform my table data to another shape defined as DTO. – Avik Aggarwal Oct 16 '20 at 06:08
  • Spring Data JPA Reference - https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.custom-implementations – Munish Chandel Dec 27 '20 at 13:03
  • Convoluted answer and doesn't work. What do we even inject to our main class? the Impl or Repository class? both ways I'm still getting the same error - Also - I have a JPA method on the `extends JpaRepository<>` interface that I need to use – ennth May 09 '21 at 00:31
  • Does CustomCustomerRepositoryImpl need to have annotation @Repository – khacsinhcs Oct 05 '22 at 16:24
2

In case you have many repositories to deal with, and your need in EntityManager is not specific for any particular repository, it is possible to implement various EntityManager functionality in a single helper class, maybe something like that:

@Service
public class RepositoryHelper {

    @PersistenceContext
    private EntityManager em;

    @Transactional
    public <E, R> R refreshAndUse(
            E entity,
            Function<E, R> usageFunction) {
        em.refresh(entity);
        return usageFunction.apply(entity);
    }

}

The refreshAndUse method here is a sample method to consume a detached entity instance, perform a refresh for it and return a result of a custom function to be applied to the refreshed entity in a declarative transaction context. And you can add other methods too, including query ones...

E_net4
  • 27,810
  • 13
  • 101
  • 139
Sergey Ushakov
  • 2,425
  • 1
  • 24
  • 15