From 14c97f0b5b7bf0479d45b613af700f55c205f93b Mon Sep 17 00:00:00 2001 From: Andrea Boriero Date: Mon, 30 Nov 2015 15:26:33 +0000 Subject: [PATCH] HHH-10396 - Add tests for the issue --- .../foreignkeys/ForeignKeyGenerationTest.java | 143 ++++++++++++++++++ .../test/schemaupdate/foreignkeys/Group.java | 25 +++ .../test/schemaupdate/foreignkeys/User.java | 38 +++++ .../schemaupdate/foreignkeys/UserSetting.java | 32 ++++ 4 files changed, 238 insertions(+) create mode 100644 hibernate-core/src/test/java/org/hibernate/test/schemaupdate/foreignkeys/ForeignKeyGenerationTest.java create mode 100644 hibernate-core/src/test/java/org/hibernate/test/schemaupdate/foreignkeys/Group.java create mode 100644 hibernate-core/src/test/java/org/hibernate/test/schemaupdate/foreignkeys/User.java create mode 100644 hibernate-core/src/test/java/org/hibernate/test/schemaupdate/foreignkeys/UserSetting.java diff --git a/hibernate-core/src/test/java/org/hibernate/test/schemaupdate/foreignkeys/ForeignKeyGenerationTest.java b/hibernate-core/src/test/java/org/hibernate/test/schemaupdate/foreignkeys/ForeignKeyGenerationTest.java new file mode 100644 index 0000000000..7b1324b4d4 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/schemaupdate/foreignkeys/ForeignKeyGenerationTest.java @@ -0,0 +1,143 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: Apache License, Version 2.0 + * See the LICENSE file in the root directory or visit http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.hibernate.test.schemaupdate.foreignkeys; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.List; + +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.registry.StandardServiceRegistry; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.boot.spi.MetadataImplementor; +import org.hibernate.tool.hbm2ddl.SchemaExport; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.junit4.BaseUnitTestCase; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; + +/** + * @author Andrea Boriero + */ + +public class ForeignKeyGenerationTest extends BaseUnitTestCase { + private File output; + private StandardServiceRegistry ssr; + private MetadataImplementor metadata; + + @Before + public void setUp() throws IOException { + output = File.createTempFile( "update_script", ".sql" ); + output.deleteOnExit(); + ssr = new StandardServiceRegistryBuilder().build(); + } + + @After + public void tearsDown() { + StandardServiceRegistryBuilder.destroy( ssr ); + } + + @Test + @TestForIssue(jiraKey = "HHH-9591") + public void oneToOneTest() throws Exception { + createSchema( new Class[] {User.class, UserSetting.class, Group.class} ); + + /* + The generated SQL for the foreign keys should be: + alter table USERS add constraint FK_TO_USER_SETTING foreign key (USER_SETTING_ID) references USER_SETTING + alter table USER_SETTING add constraint FK_TO_USER foreign key (USERS_ID) references USERS + */ + checkAlterTableStatement( new AlterTableStatement( + "USERS", + "FK_TO_USER_SETTING", + "USER_SETTING_ID", + "USER_SETTING" + ) ); + checkAlterTableStatement( new AlterTableStatement( + "USER_SETTING", + "FK_TO_USER", + "USER_ID", + "USERS" + ) ); + } + + @Test + @TestForIssue(jiraKey = "HHH-10396") + public void oneToManyTest() throws Exception { + createSchema( new Class[] {User.class, UserSetting.class, Group.class} ); + + /* + The generated SQL for the foreign keys should be: + alter table GROUP add constraint FK_USER_GROUP foreign key (USER_ID) references USERS + */ + checkAlterTableStatement( new AlterTableStatement( + "GROUP", + "FK_USER_GROUP", + "USER_ID", + "USERS" + ) ); + } + + private void createSchema(Class[] annotatedClasses) { + final MetadataSources metadataSources = new MetadataSources( ssr ); + + for ( Class c : annotatedClasses ) { + metadataSources.addAnnotatedClass( c ); + } + metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.validate(); + final SchemaExport schemaExport = new SchemaExport( metadata ) + .setHaltOnError( true ) + .setOutputFile( output.getAbsolutePath() ) + .setFormat( false ); + schemaExport.create( true, false ); + } + + private void checkAlterTableStatement(AlterTableStatement alterTableStatement) + throws Exception { + final String expectedAlterTableStatement = alterTableStatement.toSQL(); + final List sqlLines = Files.readAllLines( output.toPath() ); + boolean found = false; + for ( String line : sqlLines ) { + if ( line.contains( expectedAlterTableStatement ) ) { + found = true; + return; + } + } + assertThat( "Expected alter table statement not found : " + expectedAlterTableStatement, found, is( true ) ); + } + + private static class AlterTableStatement { + final String tableName; + final String fkConstraintName; + final String fkColumnName; + final String referenceTableName; + + public AlterTableStatement( + String tableName, + String fkConstraintName, + String fkColumnName, + String referenceTableName) { + this.tableName = tableName; + this.fkConstraintName = fkConstraintName; + this.fkColumnName = fkColumnName; + this.referenceTableName = referenceTableName; + } + + public String toSQL() { + return "alter table " + tableName + " add constraint " + fkConstraintName + " foreign key (" + fkColumnName + ") references " + referenceTableName; + } + } + +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/schemaupdate/foreignkeys/Group.java b/hibernate-core/src/test/java/org/hibernate/test/schemaupdate/foreignkeys/Group.java new file mode 100644 index 0000000000..1f92976415 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/schemaupdate/foreignkeys/Group.java @@ -0,0 +1,25 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.test.schemaupdate.foreignkeys; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import java.io.Serializable; + +/** + * @author Andrea Boriero + */ +@Entity +@Table(name = "GROUP") +public class Group implements Serializable { + @Id + @Column(name = "GROUP_ID") + private Long id; +} + diff --git a/hibernate-core/src/test/java/org/hibernate/test/schemaupdate/foreignkeys/User.java b/hibernate-core/src/test/java/org/hibernate/test/schemaupdate/foreignkeys/User.java new file mode 100644 index 0000000000..6655dd0375 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/schemaupdate/foreignkeys/User.java @@ -0,0 +1,38 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.test.schemaupdate.foreignkeys; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.ForeignKey; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import java.util.List; + +/** + * @author Andrea Boriero + */ +@Entity +@Table(name = "USERS") +public class User { + @Id + @GeneratedValue + @Column(name = "USER_ID") + private long id; + + @OneToOne(targetEntity = UserSetting.class) + @JoinColumn(name = "USER_SETTING_ID", foreignKey = @ForeignKey(name = "FK_TO_USER_SETTING")) + private UserSetting userSetting; + + @OneToMany(targetEntity = Group.class) + @JoinColumn(name = "USER_ID", foreignKey = @ForeignKey(name = "FK_USER_GROUP")) + private List groups; +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/schemaupdate/foreignkeys/UserSetting.java b/hibernate-core/src/test/java/org/hibernate/test/schemaupdate/foreignkeys/UserSetting.java new file mode 100644 index 0000000000..3d81793c4c --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/schemaupdate/foreignkeys/UserSetting.java @@ -0,0 +1,32 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.test.schemaupdate.foreignkeys; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.ForeignKey; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +/** + * @author Andrea Boriero + */ +@Entity +@Table(name = "USER_SETTING") +public class UserSetting { + @Id + @GeneratedValue + @Column(name = "USER_SETTING_ID") + public long id; + + @OneToOne + @JoinColumn(name = "USER_ID", foreignKey = @ForeignKey(name = "FK_TO_USER")) + private User user; +}