Commit bb4e5597 authored by Stephane Nicoll's avatar Stephane Nicoll

Let Hibernate detect the dialect to use

Closes gh-16172
parent 5f6d8e1e
......@@ -105,8 +105,12 @@ public abstract class JpaBaseConfiguration implements BeanFactoryAware {
public JpaVendorAdapter jpaVendorAdapter() {
AbstractJpaVendorAdapter adapter = createJpaVendorAdapter();
adapter.setShowSql(this.properties.isShowSql());
adapter.setDatabase(this.properties.determineDatabase(this.dataSource));
adapter.setDatabasePlatform(this.properties.getDatabasePlatform());
if (this.properties.getDatabase() != null) {
adapter.setDatabase(this.properties.getDatabase());
}
if (this.properties.getDatabasePlatform() != null) {
adapter.setDatabasePlatform(this.properties.getDatabasePlatform());
}
adapter.setGenerateDdl(this.properties.isGenerateDdl());
return adapter;
}
......
/*
* Copyright 2012-2018 the original author or authors.
* Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -134,7 +134,10 @@ public class JpaProperties {
* {@link DataSource}.
* @param dataSource the auto-configured data source
* @return {@code Database}
* @deprecated since 2.2.0 in favor of letting the JPA container detect the database
* to use.
*/
@Deprecated
public Database determineDatabase(DataSource dataSource) {
if (this.database != null) {
return this.database;
......
......@@ -110,14 +110,14 @@ public class CustomHibernateJpaAutoConfigurationTests {
}
@Test
public void defaultDatabaseForH2() {
public void defaultDatabaseIsSet() {
this.contextRunner.withPropertyValues("spring.datasource.url:jdbc:h2:mem:testdb",
"spring.datasource.initialization-mode:never").run((context) -> {
HibernateJpaVendorAdapter bean = context
.getBean(HibernateJpaVendorAdapter.class);
Database database = (Database) ReflectionTestUtils.getField(bean,
"database");
assertThat(database).isEqualTo(Database.H2);
assertThat(database).isEqualTo(Database.DEFAULT);
});
}
......
/*
* Copyright 2012-2018 the original author or authors.
* Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -44,25 +44,6 @@ public class HibernateDefaultDdlAutoProviderTests {
HibernateJpaAutoConfiguration.class))
.withPropertyValues("spring.datasource.initialization-mode:never");
@Test
public void defaultDdlAutoForMysql() {
// Set up environment so we get a MySQL database but don't require server to be
// running...
this.contextRunner.withPropertyValues(
"spring.datasource.type:"
+ org.apache.tomcat.jdbc.pool.DataSource.class.getName(),
"spring.datasource.database:mysql",
"spring.datasource.url:jdbc:mysql://localhost/nonexistent",
"spring.jpa.database:MYSQL").run((context) -> {
HibernateDefaultDdlAutoProvider ddlAutoProvider = new HibernateDefaultDdlAutoProvider(
Collections.emptyList());
assertThat(ddlAutoProvider
.getDefaultDdlAuto(context.getBean(DataSource.class)))
.isEqualTo("none");
});
}
@Test
public void defaultDDlAutoForEmbedded() {
this.contextRunner.run((context) -> {
......
......@@ -25,6 +25,7 @@ import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
......@@ -37,6 +38,7 @@ import com.zaxxer.hikari.HikariDataSource;
import org.hibernate.boot.model.naming.ImplicitNamingStrategy;
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform;
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
import org.hibernate.internal.SessionFactoryImpl;
......@@ -65,7 +67,9 @@ import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import static org.assertj.core.api.Assertions.assertThat;
......@@ -155,6 +159,40 @@ public class HibernateJpaAutoConfigurationTests
.run((context) -> assertThat(context).hasNotFailed());
}
@Test
public void hibernateDialectIsNotSetByDefault() {
contextRunner().run(assertJpaVendorAdapter(
(adapter) -> assertThat(adapter.getJpaPropertyMap())
.doesNotContainKeys("hibernate.dialect")));
}
@Test
public void hibernateDialectIsSetWhenDatabaseIsSet() {
contextRunner().withPropertyValues("spring.jpa.database=H2")
.run(assertJpaVendorAdapter(
(adapter) -> assertThat(adapter.getJpaPropertyMap()).contains(
entry("hibernate.dialect", H2Dialect.class.getName()))));
}
@Test
public void hibernateDialectIsSetWhenDatabasePlatformIsSet() {
String databasePlatform = TestH2Dialect.class.getName();
contextRunner()
.withPropertyValues("spring.jpa.database-platform=" + databasePlatform)
.run(assertJpaVendorAdapter(
(adapter) -> assertThat(adapter.getJpaPropertyMap())
.contains(entry("hibernate.dialect", databasePlatform))));
}
private ContextConsumer<AssertableApplicationContext> assertJpaVendorAdapter(
Consumer<HibernateJpaVendorAdapter> adapter) {
return (context) -> {
assertThat(context).hasSingleBean(JpaVendorAdapter.class);
assertThat(context).hasSingleBean(HibernateJpaVendorAdapter.class);
adapter.accept(context.getBean(HibernateJpaVendorAdapter.class));
};
}
@Test
public void jtaDefaultPlatform() {
contextRunner()
......@@ -597,4 +635,8 @@ public class HibernateJpaAutoConfigurationTests
}
public static class TestH2Dialect extends H2Dialect {
}
}
......@@ -1926,15 +1926,8 @@ conditions, it has different defaults. If an embedded database is used and no sc
manager (such as Liquibase or Flyway) is handling the `DataSource`, it defaults to
`create-drop`. In all other cases, it defaults to `none`.
The dialect to use is also automatically detected based on the current `DataSource`, but
you can set `spring.jpa.database` yourself if you want to be explicit and bypass that
check on startup.
NOTE: Specifying a `database` leads to the configuration of a well-defined Hibernate
dialect. Several databases have more than one `Dialect`, and this may not suit your needs.
In that case, you can either set `spring.jpa.database` to `default` to let Hibernate
figure things out or set the dialect by setting the `spring.jpa.database-platform`
property.
The dialect to use is detected by the JPA provider. If you prefer to set the dialect
yourself, set the `spring.jpa.database-platform` property.
The most common options to set are shown in the following example:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment