|
| 1 | +/* |
| 2 | + * Hibernate, Relational Persistence for Idiomatic Java |
| 3 | + * |
| 4 | + * License: GNU Lesser General Public License (LGPL), version 2.1 or later |
| 5 | + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html |
| 6 | + */ |
| 7 | +package org.hibernate.test.schemaupdate; |
| 8 | + |
| 9 | +import java.io.File; |
| 10 | +import java.io.IOException; |
| 11 | +import java.nio.file.Files; |
| 12 | +import java.util.EnumSet; |
| 13 | +import java.util.regex.Matcher; |
| 14 | +import java.util.regex.Pattern; |
| 15 | +import javax.persistence.Column; |
| 16 | +import javax.persistence.Entity; |
| 17 | +import javax.persistence.Id; |
| 18 | + |
| 19 | +import org.hibernate.boot.MetadataSources; |
| 20 | +import org.hibernate.boot.registry.StandardServiceRegistry; |
| 21 | +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; |
| 22 | +import org.hibernate.boot.spi.MetadataImplementor; |
| 23 | +import org.hibernate.cfg.AvailableSettings; |
| 24 | +import org.hibernate.dialect.Dialect; |
| 25 | +import org.hibernate.tool.hbm2ddl.SchemaExport; |
| 26 | +import org.hibernate.tool.hbm2ddl.SchemaUpdate; |
| 27 | +import org.hibernate.tool.hbm2ddl.SchemaValidator; |
| 28 | +import org.hibernate.tool.schema.JdbcMetadaAccessStrategy; |
| 29 | +import org.hibernate.tool.schema.TargetType; |
| 30 | + |
| 31 | +import org.hibernate.testing.TestForIssue; |
| 32 | +import org.junit.After; |
| 33 | +import org.junit.Before; |
| 34 | +import org.junit.Test; |
| 35 | +import org.junit.runner.RunWith; |
| 36 | +import org.junit.runners.Parameterized; |
| 37 | + |
| 38 | +import static org.hamcrest.core.Is.is; |
| 39 | +import static org.junit.Assert.assertThat; |
| 40 | + |
| 41 | +@TestForIssue(jiraKey = "HHH-13788") |
| 42 | +@RunWith(Parameterized.class) |
| 43 | +public class SchemaUpdateWithUseJdbcMetadataDefaultsSettingToFalseAndQuotedNameTest { |
| 44 | + @Parameterized.Parameters |
| 45 | + public static String[] parameters() { |
| 46 | + return new String[] { |
| 47 | + JdbcMetadaAccessStrategy.GROUPED.toString(), |
| 48 | + JdbcMetadaAccessStrategy.INDIVIDUALLY.toString() |
| 49 | + }; |
| 50 | + } |
| 51 | + |
| 52 | + @Parameterized.Parameter |
| 53 | + public String jdbcMetadataExtractorStrategy; |
| 54 | + |
| 55 | + private File updateOutputFile; |
| 56 | + private File createOutputFile; |
| 57 | + private StandardServiceRegistry ssr; |
| 58 | + private MetadataImplementor metadata; |
| 59 | + |
| 60 | + @Before |
| 61 | + public void setUp() throws IOException { |
| 62 | + createOutputFile = File.createTempFile( "create_script", ".sql" ); |
| 63 | + createOutputFile.deleteOnExit(); |
| 64 | + updateOutputFile = File.createTempFile( "update_script", ".sql" ); |
| 65 | + updateOutputFile.deleteOnExit(); |
| 66 | + ssr = new StandardServiceRegistryBuilder() |
| 67 | + .applySetting( "hibernate.temp.use_jdbc_metadata_defaults", "false" ) |
| 68 | + .applySetting( AvailableSettings.SHOW_SQL, "true" ) |
| 69 | + .applySetting( |
| 70 | + AvailableSettings.HBM2DDL_JDBC_METADATA_EXTRACTOR_STRATEGY, |
| 71 | + jdbcMetadataExtractorStrategy |
| 72 | + ) |
| 73 | + .build(); |
| 74 | + |
| 75 | + final MetadataSources metadataSources = new MetadataSources( ssr ); |
| 76 | + metadataSources.addAnnotatedClass( AnotherTestEntity.class ); |
| 77 | + |
| 78 | + metadata = (MetadataImplementor) metadataSources.buildMetadata(); |
| 79 | + metadata.validate(); |
| 80 | + } |
| 81 | + |
| 82 | + @After |
| 83 | + public void tearDown() { |
| 84 | + new SchemaExport().setHaltOnError( true ) |
| 85 | + .setFormat( false ) |
| 86 | + .drop( EnumSet.of( TargetType.DATABASE ), metadata ); |
| 87 | + StandardServiceRegistryBuilder.destroy( ssr ); |
| 88 | + } |
| 89 | + |
| 90 | + @Test |
| 91 | + public void testSchemaUpdateDoesNotTryToRecreateExistingTables() |
| 92 | + throws Exception { |
| 93 | + createSchema(); |
| 94 | + |
| 95 | + new SchemaUpdate().setHaltOnError( true ) |
| 96 | + .setOutputFile( updateOutputFile.getAbsolutePath() ) |
| 97 | + .setFormat( false ) |
| 98 | + .execute( EnumSet.of( TargetType.DATABASE, TargetType.SCRIPT ), metadata ); |
| 99 | + |
| 100 | + checkNoUpdateStatementHasBeenGenerated(); |
| 101 | + } |
| 102 | + |
| 103 | + private void checkNoUpdateStatementHasBeenGenerated() throws IOException { |
| 104 | + final String fileContent = new String( Files.readAllBytes( updateOutputFile.toPath() ) ); |
| 105 | + assertThat( |
| 106 | + "The update output file should be empty because the db schema had already been generated and the domain model was not modified", |
| 107 | + fileContent, |
| 108 | + is( "" ) |
| 109 | + ); |
| 110 | + } |
| 111 | + |
| 112 | + private void createSchema() throws Exception { |
| 113 | + new SchemaUpdate().setHaltOnError( true ) |
| 114 | + .setOutputFile( createOutputFile.getAbsolutePath() ) |
| 115 | + .execute( EnumSet.of( TargetType.DATABASE, TargetType.SCRIPT ), metadata ); |
| 116 | + new SchemaValidator().validate( metadata ); |
| 117 | + checkSchemaHasBeenGenerated(); |
| 118 | + } |
| 119 | + |
| 120 | + private void checkSchemaHasBeenGenerated() throws Exception { |
| 121 | + String fileContent = new String( Files.readAllBytes( createOutputFile.toPath() ) ); |
| 122 | + final Dialect dialect = metadata.getDatabase().getDialect(); |
| 123 | + Pattern fileContentPattern; |
| 124 | + if ( dialect.openQuote() == '[' ) { |
| 125 | + fileContentPattern = Pattern.compile( "create( (column|row))? table " + "\\[" + "another_test_entity" + "\\]" ); |
| 126 | + } |
| 127 | + else { |
| 128 | + fileContentPattern = Pattern.compile( "create( (column|row))? table " + dialect.openQuote() + "another_test_entity" + dialect |
| 129 | + .closeQuote() ); |
| 130 | + } |
| 131 | + Matcher fileContentMatcher = fileContentPattern.matcher( fileContent.toLowerCase() ); |
| 132 | + assertThat( |
| 133 | + "The schema has not been correctly generated, Script file : " + fileContent.toLowerCase(), |
| 134 | + fileContentMatcher.find(), |
| 135 | + is( true ) |
| 136 | + ); |
| 137 | + } |
| 138 | + |
| 139 | + @Entity(name = "`Another_Test_Entity`") |
| 140 | + public static class AnotherTestEntity { |
| 141 | + @Id |
| 142 | + private Long id; |
| 143 | + |
| 144 | + @Column(name = "`another_NAME`") |
| 145 | + private String name; |
| 146 | + } |
| 147 | +} |
0 commit comments