Skip to content

Commit 22de430

Browse files
committed
Polish "When pool autocommit is disabled, inform Hibernate"
Closes gh-9737
1 parent d0e70e9 commit 22de430

File tree

6 files changed

+106
-17
lines changed

6 files changed

+106
-17
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.boot.autoconfigure.orm.jpa;
1818

19+
import java.util.Collection;
1920
import java.util.Collections;
2021
import java.util.LinkedHashMap;
2122
import java.util.List;
@@ -77,7 +78,8 @@ class HibernateJpaConfiguration extends JpaBaseConfiguration {
7778
"org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform", };
7879

7980
private final HibernateDefaultDdlAutoProvider defaultDdlAutoProvider;
80-
private final Collection<DataSourcePoolMetadataProvider> metadataProviders;
81+
82+
private DataSourcePoolMetadataProvider poolMetadataProvider;
8183

8284
HibernateJpaConfiguration(DataSource dataSource, JpaProperties jpaProperties,
8385
ObjectProvider<JtaTransactionManager> jtaTransactionManager,
@@ -88,7 +90,8 @@ class HibernateJpaConfiguration extends JpaBaseConfiguration {
8890
transactionManagerCustomizers);
8991
this.defaultDdlAutoProvider = new HibernateDefaultDdlAutoProvider(
9092
providers.getIfAvailable(Collections::emptyList));
91-
this.metadataProviders = metadataProviders.getIfAvailable();
93+
this.poolMetadataProvider = new CompositeDataSourcePoolMetadataProvider(
94+
metadataProviders.getIfAvailable());
9295
}
9396

9497
@Override
@@ -136,17 +139,18 @@ private void configureJtaPlatform(Map<String, Object> vendorProperties)
136139
}
137140

138141
private void configureProviderDisablesAutocommit(Map<String, Object> vendorProperties) {
139-
CompositeDataSourcePoolMetadataProvider poolMetadataProvider = new CompositeDataSourcePoolMetadataProvider(
140-
this.metadataProviders);
141-
DataSourcePoolMetadata poolMetadata = poolMetadataProvider
142-
.getDataSourcePoolMetadata(getDataSource());
143-
if (poolMetadata != null
144-
&& Boolean.FALSE.equals(poolMetadata.getDefaultAutoCommit())
145-
&& getJtaTransactionManager() == null) {
142+
if (isDataSourceAutoCommitDisabled() && !isJta()) {
146143
vendorProperties.put(PROVIDER_DISABLES_AUTOCOMMIT, "true");
147144
}
148145
}
149146

147+
private boolean isDataSourceAutoCommitDisabled() {
148+
DataSourcePoolMetadata poolMetadata = this.poolMetadataProvider
149+
.getDataSourcePoolMetadata(getDataSource());
150+
return poolMetadata != null
151+
&& Boolean.FALSE.equals(poolMetadata.getDefaultAutoCommit());
152+
}
153+
150154
private boolean runningOnWebSphere() {
151155
return ClassUtils.isPresent(
152156
"com.ibm.websphere.jtaextensions." + "ExtendedJTATransaction",

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import javax.transaction.TransactionManager;
3434
import javax.transaction.UserTransaction;
3535

36+
import com.zaxxer.hikari.HikariDataSource;
3637
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
3738
import org.junit.Test;
3839

@@ -52,6 +53,7 @@
5253
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
5354

5455
import static org.assertj.core.api.Assertions.assertThat;
56+
import static org.assertj.core.api.Assertions.entry;
5557
import static org.mockito.Mockito.mock;
5658

5759
/**
@@ -75,12 +77,12 @@ public void testDataScriptWithMissingDdl() {
7577
contextRunner().withPropertyValues("spring.datasource.data:classpath:/city.sql",
7678
// Missing:
7779
"spring.datasource.schema:classpath:/ddl.sql").run((context) -> {
78-
assertThat(context).hasFailed();
79-
assertThat(context.getStartupFailure())
80-
.hasMessageContaining("ddl.sql");
81-
assertThat(context.getStartupFailure())
82-
.hasMessageContaining("spring.datasource.schema");
83-
});
80+
assertThat(context).hasFailed();
81+
assertThat(context.getStartupFailure())
82+
.hasMessageContaining("ddl.sql");
83+
assertThat(context.getStartupFailure())
84+
.hasMessageContaining("spring.datasource.schema");
85+
});
8486
}
8587

8688
@Test
@@ -105,7 +107,7 @@ public void testDataScriptRunsEarly() {
105107
"spring.datasource.data:classpath:/city.sql")
106108
.run((context) -> assertThat(
107109
context.getBean(TestInitializedJpaConfiguration.class).called)
108-
.isTrue());
110+
.isTrue());
109111
}
110112

111113
@Test
@@ -164,7 +166,7 @@ public void jtaCustomPlatform() {
164166
.getJpaPropertyMap();
165167
assertThat((String) jpaPropertyMap
166168
.get("hibernate.transaction.jta.platform"))
167-
.isEqualTo(TestJtaPlatform.class.getName());
169+
.isEqualTo(TestJtaPlatform.class.getName());
168170
});
169171
}
170172

@@ -194,6 +196,62 @@ public void autoConfigurationBacksOffWithSeveralDataSources() {
194196
});
195197
}
196198

199+
@Test
200+
public void providerDisablesAutoCommitIsConfigured() {
201+
contextRunner().withPropertyValues(
202+
"spring.datasource.type:" + HikariDataSource.class.getName(),
203+
"spring.datasource.hikari.auto-commit:false").run((context) -> {
204+
Map<String, Object> jpaProperties = context
205+
.getBean(LocalContainerEntityManagerFactoryBean.class)
206+
.getJpaPropertyMap();
207+
assertThat(jpaProperties).contains(entry(
208+
"hibernate.connection.provider_disables_autocommit", "true"));
209+
});
210+
}
211+
212+
@Test
213+
public void providerDisablesAutoCommitIsNotConfiguredIfAutoCommitIsEnabled() {
214+
contextRunner().withPropertyValues(
215+
"spring.datasource.type:" + HikariDataSource.class.getName(),
216+
"spring.datasource.hikari.auto-commit:true").run((context) -> {
217+
Map<String, Object> jpaProperties = context
218+
.getBean(LocalContainerEntityManagerFactoryBean.class)
219+
.getJpaPropertyMap();
220+
assertThat(jpaProperties).doesNotContainKeys(
221+
"hibernate.connection.provider_disables_autocommit");
222+
});
223+
}
224+
225+
@Test
226+
public void providerDisablesAutoCommitIsNotConfiguredIfPropertyIsSet() {
227+
contextRunner().withPropertyValues(
228+
"spring.datasource.type:" + HikariDataSource.class.getName(),
229+
"spring.datasource.hikari.auto-commit:false",
230+
"spring.jpa.properties.hibernate.connection.provider_disables_autocommit=false"
231+
).run((context) -> {
232+
Map<String, Object> jpaProperties = context
233+
.getBean(LocalContainerEntityManagerFactoryBean.class)
234+
.getJpaPropertyMap();
235+
assertThat(jpaProperties).contains(entry(
236+
"hibernate.connection.provider_disables_autocommit", "false"));
237+
});
238+
}
239+
240+
@Test
241+
public void providerDisablesAutoCommitIsNotConfiguredWihJta() {
242+
contextRunner()
243+
.withConfiguration(AutoConfigurations.of(JtaAutoConfiguration.class))
244+
.withPropertyValues(
245+
"spring.datasource.type:" + HikariDataSource.class.getName(),
246+
"spring.datasource.hikari.auto-commit:false").run((context) -> {
247+
Map<String, Object> jpaProperties = context
248+
.getBean(LocalContainerEntityManagerFactoryBean.class)
249+
.getJpaPropertyMap();
250+
assertThat(jpaProperties).doesNotContainKeys(
251+
"hibernate.connection.provider_disables_autocommit");
252+
});
253+
}
254+
197255
@Configuration
198256
@TestAutoConfigurationPackage(City.class)
199257
static class TestInitializedJpaConfiguration {

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/AbstractDataSourcePoolMetadataTests.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ public void getPoolSizeTwoConnections() {
8686
@Test
8787
public abstract void getValidationQuery();
8888

89+
@Test
90+
public abstract void getDefaultAutoCommit();
91+
8992
protected DataSourceBuilder<?> initializeBuilder() {
9093
return DataSourceBuilder.create().driverClassName("org.hsqldb.jdbc.JDBCDriver")
9194
.url("jdbc:hsqldb:mem:test").username("sa");

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/CommonsDbcp2DataSourcePoolMetadataTests.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,14 @@ public void getValidationQuery() {
8181
.isEqualTo("SELECT FROM FOO");
8282
}
8383

84+
@Override
85+
public void getDefaultAutoCommit() {
86+
BasicDataSource dataSource = createDataSource();
87+
dataSource.setDefaultAutoCommit(false);
88+
assertThat(new CommonsDbcp2DataSourcePoolMetadata(dataSource)
89+
.getDefaultAutoCommit()).isFalse();
90+
}
91+
8492
private CommonsDbcp2DataSourcePoolMetadata createDataSourceMetadata(int minSize,
8593
int maxSize) {
8694
BasicDataSource dataSource = createDataSource();

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/HikariDataSourcePoolMetadataTests.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ public void getValidationQuery() {
5050
.isEqualTo("SELECT FROM FOO");
5151
}
5252

53+
@Override
54+
public void getDefaultAutoCommit() {
55+
HikariDataSource dataSource = createDataSource(0, 4);
56+
dataSource.setAutoCommit(false);
57+
assertThat(new HikariDataSourcePoolMetadata(dataSource).getDefaultAutoCommit())
58+
.isFalse();
59+
}
60+
5361
private HikariDataSource createDataSource(int minSize, int maxSize) {
5462
HikariDataSource dataSource = initializeBuilder().type(HikariDataSource.class)
5563
.build();

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/TomcatDataSourcePoolMetadataTests.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ public void getValidationQuery() {
5050
.isEqualTo("SELECT FROM FOO");
5151
}
5252

53+
@Override
54+
public void getDefaultAutoCommit() {
55+
DataSource dataSource = createDataSource(0, 4);
56+
dataSource.setDefaultAutoCommit(false);
57+
assertThat(new TomcatDataSourcePoolMetadata(dataSource).getDefaultAutoCommit())
58+
.isFalse();
59+
}
60+
5361
private DataSource createDataSource(int minSize, int maxSize) {
5462
DataSource dataSource = initializeBuilder().type(DataSource.class).build();
5563
dataSource.setMinIdle(minSize);

0 commit comments

Comments
 (0)