Oliver Drotbohm opened SPR-10443 and commented
Currently you can inject any Spring bean into clients through constructor injection. A JPA EntityManager
is an exception to that. Constructor injection has the benefit of being able to design classes in an immutable way. Also, you communicate required dependencies through it easily. Sadly, @PersistenceContext
cannot be used on a constructor parameter and this probably won't change befor JPA 2.2 (giving 2.1 is close to final).
It would be cool to simply be able to inject EntityManager
instances through either @Autowired
or @Inject
.
Issue Links: - DATAJPA-445 Enable support to inject EntityManager via constructor
12 votes, 17 watchers
Comment From: spring-projects-issues
Oliver Drotbohm commented
Created a ticket in Spring Data JPA to locally implement the support in there as it should be easy to add to the already registered bean definitions.
Comment From: spring-projects-issues
Oliver Drotbohm commented
We've implemented the support in Spring Data JPA and it seems generally useable even in a non Spring Data context. Activation of annotation based configuration could register the BeanFactoryPostProcessor
as well.
Comment From: spring-projects-issues
Marcel Overdijk commented
To bad this is not possible yet. Especially in the light of http://olivergierke.de/2013/11/why-field-injection-is-evil/
Comment From: spring-projects-issues
Oliver Drotbohm commented
Marcel Overdijk – Care to elaborate why the Spring Data JPA support for that is insufficient?
Comment From: spring-projects-issues
Marcel Overdijk commented
Oliver Drotbohm I have a project not using Spring Data. In a earlier post you mentioned support in Spring Data JPA which seems generally usable even in a non Spring Data context. What do you mean exactly with that?
Comment From: spring-projects-issues
Francisco Lozano commented
I also want to use constructor-injection of EntityManager without Spring Data JPA, feels weird that field injection is forced here. An @Autowired
constructor should work...
Comment From: lucasoares
Will this be fixed anytime soon?
Comment From: jhoeller
For the time being, a plain Spring application can define a bean of type org.springframework.orm.jpa.support.SharedEntityManagerBean
, wiring it to a specific EntityManagerFactory
, potentially defining a qualifier on it (e.g. the persistence unit name) - and then injecting it via @Autowired
and the common qualifier mechanism if necessary, or simply through a plain constructor argument.
Due to the separate nature of the shared EntityManager
instance, there is no first-class mechanism to do so implicitly. An explicit SharedEntityManagerBean
is a straightforward FactoryBean
matched by type and does not require additional post-processors. Alternatively, you could declare an @Bean
method which returns an EntityManager
built through SharedEntityManagerCreator.createSharedEntityManager
, not even involving a FactoryBean
then:
@Bean
public EntityManager sharedEntityManager(EntityManagerFactory emf) {
return SharedEntityManagerCreator.createSharedEntityManager(emf);
}
That's essentially what Spring Data JPA's post-processor ends up registering as well. If there is nothing else we can do at the core Spring Framework level, maybe we should explicitly show the approach above in the reference documentation.