/*
* Copyright 2012-2017 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.orm.jpa;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.Map;
import javax.sql.DataSource;
import org.hibernate.cfg.AvailableSettings;
import org.junit.After;
import org.junit.Test;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy;
import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy;
import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.vendor.Database;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
/**
* Tests for {@link JpaProperties}.
*
* @author Stephane Nicoll
*/
public class JpaPropertiesTests {
private AnnotationConfigApplicationContext context;
@After
public void close() {
if (this.context != null) {
this.context.close();
}
}
@Test
public void noCustomNamingStrategy() throws Exception {
JpaProperties properties = load();
Map<String, String> hibernateProperties = properties
.getHibernateProperties(mockStandaloneDataSource());
assertThat(hibernateProperties)
.doesNotContainKeys("hibernate.ejb.naming_strategy");
assertThat(hibernateProperties).containsEntry(
"hibernate.physical_naming_strategy",
SpringPhysicalNamingStrategy.class.getName());
assertThat(hibernateProperties).containsEntry(
"hibernate.implicit_naming_strategy",
SpringImplicitNamingStrategy.class.getName());
}
@Test
public void hibernate5CustomNamingStrategies() throws Exception {
JpaProperties properties = load(
"spring.jpa.hibernate.naming.implicit-strategy:com.example.Implicit",
"spring.jpa.hibernate.naming.physical-strategy:com.example.Physical");
Map<String, String> hibernateProperties = properties
.getHibernateProperties(mockStandaloneDataSource());
assertThat(hibernateProperties).contains(
entry("hibernate.implicit_naming_strategy", "com.example.Implicit"),
entry("hibernate.physical_naming_strategy", "com.example.Physical"));
assertThat(hibernateProperties)
.doesNotContainKeys("hibernate.ejb.naming_strategy");
}
@Test
public void hibernate5CustomNamingStrategiesViaJpaProperties() throws Exception {
JpaProperties properties = load(
"spring.jpa.properties.hibernate.implicit_naming_strategy:com.example.Implicit",
"spring.jpa.properties.hibernate.physical_naming_strategy:com.example.Physical");
Map<String, String> hibernateProperties = properties
.getHibernateProperties(mockStandaloneDataSource());
// You can override them as we don't provide any default
assertThat(hibernateProperties).contains(
entry("hibernate.implicit_naming_strategy", "com.example.Implicit"),
entry("hibernate.physical_naming_strategy", "com.example.Physical"));
assertThat(hibernateProperties)
.doesNotContainKeys("hibernate.ejb.naming_strategy");
}
@Test
public void useNewIdGeneratorMappingsDefault() throws Exception {
JpaProperties properties = load();
Map<String, String> hibernateProperties = properties
.getHibernateProperties(mockStandaloneDataSource());
assertThat(hibernateProperties)
.containsEntry(AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, "true");
}
@Test
public void useNewIdGeneratorMappingsFalse() throws Exception {
JpaProperties properties = load(
"spring.jpa.hibernate.use-new-id-generator-mappings:false");
Map<String, String> hibernateProperties = properties
.getHibernateProperties(mockStandaloneDataSource());
assertThat(hibernateProperties)
.containsEntry(AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, "false");
}
@Test
public void determineDatabaseNoCheckIfDatabaseIsSet() throws SQLException {
JpaProperties properties = load("spring.jpa.database=postgresql");
DataSource dataSource = mockStandaloneDataSource();
Database database = properties.determineDatabase(dataSource);
assertThat(database).isEqualTo(Database.POSTGRESQL);
verify(dataSource, never()).getConnection();
}
@Test
public void determineDatabaseWithKnownUrl() {
JpaProperties properties = load();
Database database = properties
.determineDatabase(mockDataSource("jdbc:h2:mem:testdb"));
assertThat(database).isEqualTo(Database.H2);
}
@Test
public void determineDatabaseWithKnownUrlAndUserConfig() {
JpaProperties properties = load("spring.jpa.database=mysql");
Database database = properties
.determineDatabase(mockDataSource("jdbc:h2:mem:testdb"));
assertThat(database).isEqualTo(Database.MYSQL);
}
@Test
public void determineDatabaseWithUnknownUrl() {
JpaProperties properties = load();
Database database = properties
.determineDatabase(mockDataSource("jdbc:unknown://localhost"));
assertThat(database).isEqualTo(Database.DEFAULT);
}
private DataSource mockStandaloneDataSource() throws SQLException {
DataSource ds = mock(DataSource.class);
given(ds.getConnection()).willThrow(SQLException.class);
return ds;
}
private DataSource mockDataSource(String jdbcUrl) {
DataSource ds = mock(DataSource.class);
try {
DatabaseMetaData metadata = mock(DatabaseMetaData.class);
given(metadata.getURL()).willReturn(jdbcUrl);
Connection connection = mock(Connection.class);
given(connection.getMetaData()).willReturn(metadata);
given(ds.getConnection()).willReturn(connection);
}
catch (SQLException e) {
// Do nothing
}
return ds;
}
private JpaProperties load(String... environment) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
EnvironmentTestUtils.addEnvironment(ctx, environment);
ctx.register(TestConfiguration.class);
ctx.refresh();
this.context = ctx;
return this.context.getBean(JpaProperties.class);
}
@Configuration
@EnableConfigurationProperties(JpaProperties.class)
static class TestConfiguration {
}
}