Skip to content

Commit fbc265b

Browse files
committed
Add DataSource configuration/exposure to LocalEntityManagerFactoryBean
Closes gh-32344
1 parent 5acee7b commit fbc265b

File tree

2 files changed

+55
-22
lines changed

2 files changed

+55
-22
lines changed

Diff for: spring-orm/src/main/java/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.java

+7-4
Original file line numberDiff line numberDiff line change
@@ -276,8 +276,9 @@ public void setValidationMode(ValidationMode validationMode) {
276276
* @see jakarta.persistence.spi.PersistenceUnitInfo#getNonJtaDataSource()
277277
* @see #setPersistenceUnitManager
278278
*/
279-
public void setDataSource(DataSource dataSource) {
280-
this.internalPersistenceUnitManager.setDataSourceLookup(new SingleDataSourceLookup(dataSource));
279+
public void setDataSource(@Nullable DataSource dataSource) {
280+
this.internalPersistenceUnitManager.setDataSourceLookup(
281+
dataSource != null ? new SingleDataSourceLookup(dataSource) : null);
281282
this.internalPersistenceUnitManager.setDefaultDataSource(dataSource);
282283
}
283284

@@ -293,8 +294,9 @@ public void setDataSource(DataSource dataSource) {
293294
* @see jakarta.persistence.spi.PersistenceUnitInfo#getJtaDataSource()
294295
* @see #setPersistenceUnitManager
295296
*/
296-
public void setJtaDataSource(DataSource jtaDataSource) {
297-
this.internalPersistenceUnitManager.setDataSourceLookup(new SingleDataSourceLookup(jtaDataSource));
297+
public void setJtaDataSource(@Nullable DataSource jtaDataSource) {
298+
this.internalPersistenceUnitManager.setDataSourceLookup(
299+
jtaDataSource != null ? new SingleDataSourceLookup(jtaDataSource) : null);
298300
this.internalPersistenceUnitManager.setDefaultJtaDataSource(jtaDataSource);
299301
}
300302

@@ -439,6 +441,7 @@ public String getPersistenceUnitName() {
439441
}
440442

441443
@Override
444+
@Nullable
442445
public DataSource getDataSource() {
443446
if (this.persistenceUnitInfo != null) {
444447
return (this.persistenceUnitInfo.getJtaDataSource() != null ?

Diff for: spring-orm/src/main/java/org/springframework/orm/jpa/LocalEntityManagerFactoryBean.java

+48-18
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,40 +16,34 @@
1616

1717
package org.springframework.orm.jpa;
1818

19+
import javax.sql.DataSource;
20+
1921
import jakarta.persistence.EntityManagerFactory;
2022
import jakarta.persistence.Persistence;
2123
import jakarta.persistence.PersistenceException;
2224
import jakarta.persistence.spi.PersistenceProvider;
2325

26+
import org.springframework.lang.Nullable;
27+
2428
/**
2529
* {@link org.springframework.beans.factory.FactoryBean} that creates a JPA
2630
* {@link jakarta.persistence.EntityManagerFactory} according to JPA's standard
2731
* <i>standalone</i> bootstrap contract. This is the simplest way to set up a
2832
* shared JPA EntityManagerFactory in a Spring application context; the
2933
* EntityManagerFactory can then be passed to JPA-based DAOs via
3034
* dependency injection. Note that switching to a JNDI lookup or to a
31-
* {@link LocalContainerEntityManagerFactoryBean}
32-
* definition is just a matter of configuration!
35+
* {@link LocalContainerEntityManagerFactoryBean} definition based on the
36+
* JPA container contract is just a matter of configuration!
3337
*
3438
* <p>Configuration settings are usually read from a {@code META-INF/persistence.xml}
3539
* config file, residing in the class path, according to the JPA standalone bootstrap
36-
* contract. Additionally, most JPA providers will require a special VM agent
37-
* (specified on JVM startup) that allows them to instrument application classes.
38-
* See the Java Persistence API specification and your provider documentation
39-
* for setup details.
40-
*
41-
* <p>This EntityManagerFactory bootstrap is appropriate for standalone applications
42-
* which solely use JPA for data access. If you want to set up your persistence
43-
* provider for an external DataSource and/or for global transactions which span
44-
* multiple resources, you will need to either deploy it into a full Jakarta EE
45-
* application server and access the deployed EntityManagerFactory via JNDI,
46-
* or use Spring's {@link LocalContainerEntityManagerFactoryBean} with appropriate
47-
* configuration for local setup according to JPA's container contract.
40+
* contract. See the Java Persistence API specification and your persistence provider
41+
* documentation for setup details. Additionally, JPA properties can also be added
42+
* on this FactoryBean via {@link #setJpaProperties}/{@link #setJpaPropertyMap}.
4843
*
4944
* <p><b>Note:</b> This FactoryBean has limited configuration power in terms of
50-
* what configuration it is able to pass to the JPA provider. If you need more
51-
* flexible configuration, for example passing a Spring-managed JDBC DataSource
52-
* to the JPA provider, consider using Spring's more powerful
45+
* the configuration that it is able to pass to the JPA provider. If you need
46+
* more flexible configuration options, consider using Spring's more powerful
5347
* {@link LocalContainerEntityManagerFactoryBean} instead.
5448
*
5549
* @author Juergen Hoeller
@@ -67,6 +61,42 @@
6761
@SuppressWarnings("serial")
6862
public class LocalEntityManagerFactoryBean extends AbstractEntityManagerFactoryBean {
6963

64+
private static final String DATASOURCE_PROPERTY = "jakarta.persistence.dataSource";
65+
66+
67+
/**
68+
* Specify the JDBC DataSource that the JPA persistence provider is supposed
69+
* to use for accessing the database. This is an alternative to keeping the
70+
* JDBC configuration in {@code persistence.xml}, passing in a Spring-managed
71+
* DataSource through the "jakarta.persistence.dataSource" property instead.
72+
* <p>When configured here, the JDBC DataSource will also get autodetected by
73+
* {@link JpaTransactionManager} for exposing JPA transactions to JDBC accessors.
74+
* @since 6.2
75+
* @see #getJpaPropertyMap()
76+
* @see JpaTransactionManager#setDataSource
77+
*/
78+
public void setDataSource(@Nullable DataSource dataSource) {
79+
if (dataSource != null) {
80+
getJpaPropertyMap().put(DATASOURCE_PROPERTY, dataSource);
81+
}
82+
else {
83+
getJpaPropertyMap().remove(DATASOURCE_PROPERTY);
84+
}
85+
}
86+
87+
/**
88+
* Expose the JDBC DataSource from the "jakarta.persistence.dataSource"
89+
* property, if any.
90+
* @since 6.2
91+
* @see #getJpaPropertyMap()
92+
*/
93+
@Override
94+
@Nullable
95+
public DataSource getDataSource() {
96+
return (DataSource) getJpaPropertyMap().get(DATASOURCE_PROPERTY);
97+
}
98+
99+
70100
/**
71101
* Initialize the EntityManagerFactory for the given configuration.
72102
* @throws jakarta.persistence.PersistenceException in case of JPA initialization errors

0 commit comments

Comments
 (0)