Skip to content

Commit 038dda9

Browse files
committed
Document EntityManager injection via constructors/@Autowired
Closes gh-15076
1 parent 1ac0549 commit 038dda9

File tree

1 file changed

+50
-19
lines changed
  • framework-docs/modules/ROOT/pages/data-access/orm

1 file changed

+50
-19
lines changed

framework-docs/modules/ROOT/pages/data-access/orm/jpa.adoc

Lines changed: 50 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,6 @@ You can use this option for full JPA capabilities in a Spring-based application
8888
This includes web containers such as Tomcat, stand-alone applications, and
8989
integration tests with sophisticated persistence requirements.
9090

91-
NOTE: If you want to specifically configure a Hibernate setup, an immediate alternative
92-
is to set up a native Hibernate `LocalSessionFactoryBean` instead of a plain JPA
93-
`LocalContainerEntityManagerFactoryBean`, letting it interact with JPA access code
94-
as well as native Hibernate access code.
95-
See xref:data-access/orm/jpa.adoc#orm-jpa-hibernate[Native Hibernate setup for JPA interaction] for details.
96-
9791
The `LocalContainerEntityManagerFactoryBean` gives full control over
9892
`EntityManagerFactory` configuration and is appropriate for environments where
9993
fine-grained customization is required. The `LocalContainerEntityManagerFactoryBean`
@@ -187,6 +181,7 @@ and automatic propagation of the weaver to all weaver-aware beans:
187181
[source,xml,indent=0,subs="verbatim,quotes"]
188182
----
189183
<context:load-time-weaver/>
184+
190185
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
191186
...
192187
</bean>
@@ -425,20 +420,20 @@ Kotlin::
425420
----
426421
======
427422

428-
The `@PersistenceContext` annotation has an optional attribute called `type`, which defaults to
429-
`PersistenceContextType.TRANSACTION`. You can use this default to receive a shared
423+
The `@PersistenceContext` annotation has an optional attribute called `type`, which defaults
424+
to `PersistenceContextType.TRANSACTION`. You can use this default to receive a shared
430425
`EntityManager` proxy. The alternative, `PersistenceContextType.EXTENDED`, is a completely
431426
different affair. This results in a so-called extended `EntityManager`, which is not
432427
thread-safe and, hence, must not be used in a concurrently accessed component, such as a
433-
Spring-managed singleton bean. Extended `EntityManager` instances are only supposed to be used#
428+
Spring-managed singleton bean. Extended `EntityManager` instances are only supposed to be used
434429
in stateful components that, for example, reside in a session, with the lifecycle of the
435430
`EntityManager` not tied to a current transaction but rather being completely up to the
436431
application.
437432

438433
.Method- and field-level Injection
439434
****
440-
You can apply annotations that indicate dependency injections (such as `@PersistenceUnit` and
441-
`@PersistenceContext`) on field or methods inside a class -- hence the expressions
435+
You can apply annotations that indicate dependency injections (such as `@PersistenceUnit`
436+
and `@PersistenceContext`) on field or methods inside a class -- hence the expressions
442437
"`method-level injection`" and "`field-level injection`". Field-level annotations are
443438
concise and easier to use while method-level annotations allow for further processing of the
444439
injected dependency. In both cases, the member visibility (public, protected, or private)
@@ -460,12 +455,53 @@ No import of any Spring class is required. Moreover, as the JPA annotations are
460455
the injections are applied automatically by the Spring container. This is appealing from
461456
a non-invasiveness perspective and can feel more natural to JPA developers.
462457

458+
[[orm-jpa-dao-autowired]]
459+
=== Implementing DAOs Based on `@Autowired` (typically with constructor-based injection)
460+
461+
`@PersistenceUnit` and `@PersistenceContext` can only be declared on methods and fields.
462+
What about providing JPA resources via constructors and other `@Autowired` injection points?
463+
464+
`EntityManagerFactory` can easily be injected via constructors and `@Autowired` fields/methods
465+
as long as the target is defined as a bean, e.g. via `LocalContainerEntityManagerFactoryBean`.
466+
The injection point matches the original `EntityManagerFactory` definition by type as-is.
467+
468+
However, an `@PersistenceContext`-style shared `EntityManager` reference is not available for
469+
regular dependency injection out of the box. In order to make it available for type-based
470+
matching as required by `@Autowired`, consider defining a `SharedEntityManagerBean` as a
471+
companion for your `EntityManagerFactory` definition:
472+
473+
[source,xml,indent=0,subs="verbatim,quotes"]
474+
----
475+
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
476+
...
477+
</bean>
478+
479+
<bean id="em" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
480+
<property name="entityManagerFactory" ref="emf"/>
481+
</bean>
482+
----
483+
484+
Alternatively, you may define an `@Bean` method based on `SharedEntityManagerCreator`:
485+
486+
[source,java,indent=0,subs="verbatim,quotes"]
487+
----
488+
@Bean("em")
489+
public static EntityManager sharedEntityManager(EntityManagerFactory emf) {
490+
return SharedEntityManagerCreator.createSharedEntityManager(emf);
491+
}
492+
----
493+
494+
In case of multiple persistence units, each `EntityManagerFactory` definition needs to be
495+
accompanied by a corresponding `EntityManager` bean definition, ideally with qualifiers
496+
that match with the distinct `EntityManagerFactory` definition in order to distinguish
497+
the persistence units via `@Autowired @Qualifier("...")`.
498+
463499

464500
[[orm-jpa-tx]]
465-
== Spring-driven JPA transactions
501+
== Spring-driven JPA Transactions
466502

467-
NOTE: We strongly encourage you to read xref:data-access/transaction/declarative.adoc[Declarative Transaction Management], if you have not
468-
already done so, to get more detailed coverage of Spring's declarative transaction support.
503+
NOTE: We strongly encourage you to read xref:data-access/transaction/declarative.adoc[Declarative Transaction Management],
504+
if you have not already done so, to get more detailed coverage of Spring's declarative transaction support.
469505

470506
The recommended strategy for JPA is local transactions through JPA's native transaction
471507
support. Spring's `JpaTransactionManager` provides many capabilities known from local
@@ -478,11 +514,6 @@ to JDBC access code that accesses the same `DataSource`, provided that the regis
478514
Spring provides dialects for the EclipseLink and Hibernate JPA implementations.
479515
See the xref:data-access/orm/jpa.adoc#orm-jpa-dialect[next section] for details on the `JpaDialect` mechanism.
480516

481-
NOTE: As an immediate alternative, Spring's native `HibernateTransactionManager` is capable
482-
of interacting with JPA access code, adapting to several Hibernate specifics and providing
483-
JDBC interaction. This makes particular sense in combination with `LocalSessionFactoryBean`
484-
setup. See xref:data-access/orm/jpa.adoc#orm-jpa-hibernate[Native Hibernate Setup for JPA Interaction] for details.
485-
486517

487518
[[orm-jpa-dialect]]
488519
== Understanding `JpaDialect` and `JpaVendorAdapter`

0 commit comments

Comments
 (0)