Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access Spring Data configured entity manager (factory) in custom implementation

I'm writing a custom implementation for a Spring Data JPA repository. So I have:

  • MyEntityRepositoryCustom => interface with the custom methods
  • MyEntityRepositoryUmpl => implementation of the above interface
  • MyEntityRepository => standard interface which extends JpaRepository and MyEntityRepositoryCustom

My problem is this: within the implementation of MyEntityRepositoryUmpl I need to access the entity manager that was injected into Spring Data. How to get it? I can use @PersistenceContext to get it autowired, but the problem is that this repository must work in an application that sets up more than one persistence units. So, to tell Spring which one I need, I would have to use @PersistenceContext(unitName="myUnit"). However, since my repositories are defined in a reusable service layer, I can't know at that point what will be the name of the persistence unit that the higher-level application layer will configure to be injected into my repositories.

In other words, what I would need to do is to access the entity manager that Spring Data itself is using, but after a (not so quick) look at Spring Data JPA documentation I couldn't find anything for this.

Honestly, the fact that the Impl classes are totally unaware of Spring Data, although described as a strength in Spring Data manual, is actually a complication whenever you need to access something that is usually provided by Spring Data itself in your custom implementation (almost always, I would say...).

like image 787
Mauro Molinari Avatar asked Dec 22 '14 16:12

Mauro Molinari


1 Answers

Since version Spring Data JPA 1.9.2 you have access to EntityManager through JpaContext, see: http://docs.spring.io/spring-data/jpa/docs/1.9.2.RELEASE/reference/html/#jpa.misc.jpa-context. Example:

@Component
public class RepositoryUtil
{
    @Autowired
    private JpaContext jpaContext;

    public void deatach(T entity)
    {
        jpaContext.getEntityManagerByManagedType(entity.getClass()).detach(entity);
    }
}

P.S. This approach will not work if you have more than one EntityManager candidate for some Class, see implementation of JpaContext#getEntityManagerByManagedType -> DefaultJpaContext#getEntityManagerByManagedType.

like image 110
Alexander du Sautoy Avatar answered Sep 28 '22 03:09

Alexander du Sautoy