From 5c0d400c231feed12665bafcc6a35caa563c7baa Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 11 May 2016 10:11:34 +0100 Subject: [PATCH] Align Hibernate 5 join table names with those from SpringNamingStrategy Previously, the name of a join table when using Hibernate 5 would differ from those when using Hibernate 4 with the default SpringNamingStrategy. This commit introduces SpringImplicitNamingStrategy which customises the name of join tables to match those produced by SpringNamingStrategy. Closes gh-5880 --- .../autoconfigure/orm/jpa/JpaProperties.java | 5 ++- .../orm/jpa/JpaPropertiesTests.java | 8 +++- .../spring-boot-sample-jpa/pom.xml | 4 +- .../src/main/resources/import.sql | 16 +++---- .../SpringImplicitNamingStrategy.java | 43 +++++++++++++++++++ 5 files changed, 63 insertions(+), 13 deletions(-) create mode 100644 spring-boot/src/main/java/org/springframework/boot/orm/jpa/hibernate/SpringImplicitNamingStrategy.java diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaProperties.java index fb3f19484b4..db69f4c8c1c 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaProperties.java @@ -235,6 +235,8 @@ public class JpaProperties { private static final String DEFAULT_PHYSICAL_STRATEGY = "org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy"; + private static final String DEFAULT_IMPLICIT_STRATEGY = "org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy"; + /** * Hibernate 5 implicit naming strategy fully qualified name. */ @@ -288,7 +290,8 @@ public class JpaProperties { private void applyHibernate5NamingStrategy(Map properties) { applyHibernate5NamingStrategy(properties, - "hibernate.implicit_naming_strategy", this.implicitStrategy, null); + "hibernate.implicit_naming_strategy", this.implicitStrategy, + DEFAULT_IMPLICIT_STRATEGY); applyHibernate5NamingStrategy(properties, "hibernate.physical_naming_strategy", this.physicalStrategy, DEFAULT_PHYSICAL_STRATEGY); diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/JpaPropertiesTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/JpaPropertiesTests.java index aa7e44f5e15..8e77878400a 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/JpaPropertiesTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/JpaPropertiesTests.java @@ -26,6 +26,7 @@ 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.SpringNamingStrategy; import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy; import org.springframework.boot.test.util.EnvironmentTestUtils; @@ -98,11 +99,14 @@ public class JpaPropertiesTests { JpaProperties properties = load(HibernateVersion.V5); Map hibernateProperties = properties .getHibernateProperties(mockStandaloneDataSource()); - assertThat(hibernateProperties).doesNotContainKeys( - "hibernate.ejb.naming_strategy", "hibernate.implicit_naming_strategy"); + 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 diff --git a/spring-boot-samples/spring-boot-sample-jpa/pom.xml b/spring-boot-samples/spring-boot-sample-jpa/pom.xml index 498facb39de..2a0fb663640 100644 --- a/spring-boot-samples/spring-boot-sample-jpa/pom.xml +++ b/spring-boot-samples/spring-boot-sample-jpa/pom.xml @@ -28,8 +28,8 @@ hibernate-entitymanager - org.hsqldb - hsqldb + com.h2database + h2 runtime diff --git a/spring-boot-samples/spring-boot-sample-jpa/src/main/resources/import.sql b/spring-boot-samples/spring-boot-sample-jpa/src/main/resources/import.sql index 0468e3ba429..a3d2222035e 100644 --- a/spring-boot-samples/spring-boot-sample-jpa/src/main/resources/import.sql +++ b/spring-boot-samples/spring-boot-sample-jpa/src/main/resources/import.sql @@ -7,11 +7,11 @@ insert into note(title, body) values ('Spring Framework', 'Core support for depe insert into note(title, body) values ('Spring Integration', 'Extends the Spring programming model to support the well-known Enterprise Integration Patterns.') insert into note(title, body) values ('Tomcat', 'Apache Tomcat is an open source software implementation of the Java Servlet and JavaServer Pages technologies.') -insert into note_tag(notes_id, tags_id) values (1, 1) -insert into note_tag(notes_id, tags_id) values (2, 1) -insert into note_tag(notes_id, tags_id) values (3, 1) -insert into note_tag(notes_id, tags_id) values (1, 3) -insert into note_tag(notes_id, tags_id) values (2, 3) -insert into note_tag(notes_id, tags_id) values (3, 3) -insert into note_tag(notes_id, tags_id) values (4, 2) -insert into note_tag(notes_id, tags_id) values (4, 3) +insert into note_tags(notes_id, tags_id) values (1, 1) +insert into note_tags(notes_id, tags_id) values (2, 1) +insert into note_tags(notes_id, tags_id) values (3, 1) +insert into note_tags(notes_id, tags_id) values (1, 3) +insert into note_tags(notes_id, tags_id) values (2, 3) +insert into note_tags(notes_id, tags_id) values (3, 3) +insert into note_tags(notes_id, tags_id) values (4, 2) +insert into note_tags(notes_id, tags_id) values (4, 3) \ No newline at end of file diff --git a/spring-boot/src/main/java/org/springframework/boot/orm/jpa/hibernate/SpringImplicitNamingStrategy.java b/spring-boot/src/main/java/org/springframework/boot/orm/jpa/hibernate/SpringImplicitNamingStrategy.java new file mode 100644 index 00000000000..83d7f6dd686 --- /dev/null +++ b/spring-boot/src/main/java/org/springframework/boot/orm/jpa/hibernate/SpringImplicitNamingStrategy.java @@ -0,0 +1,43 @@ +/* + * Copyright 2012-2016 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.orm.jpa.hibernate; + +import org.hibernate.boot.model.naming.Identifier; +import org.hibernate.boot.model.naming.ImplicitJoinTableNameSource; +import org.hibernate.boot.model.naming.ImplicitNamingStrategy; +import org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl; + +/** + * Hibernate {@link ImplicitNamingStrategy} that follows Spring recommended naming + * conventions. Naming conventions implemented here are identical to + * {@link ImplicitNamingStrategyJpaCompliantImpl} with the exception that join table names + * are of the form + * {owning_physical_table_name}_{association_owning_property_name}. + * + * @author Andy Wilkinson + * @since 1.4.0 + */ +public class SpringImplicitNamingStrategy extends ImplicitNamingStrategyJpaCompliantImpl { + + @Override + public Identifier determineJoinTableName(ImplicitJoinTableNameSource source) { + String name = source.getOwningPhysicalTableName() + "_" + + source.getAssociationOwningAttributePath().getProperty(); + return toIdentifier(name, source.getBuildingContext()); + } + +}