/*
* 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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.test.schemaupdate;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.ForeignKey;
import javax.persistence.Id;
import javax.persistence.Index;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
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.cfg.AvailableSettings;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.hbm2ddl.SchemaUpdate;
import org.hibernate.tool.hbm2ddl.SchemaValidator;
import org.hibernate.tool.schema.JdbcMetadaAccessStrategy;
import org.hibernate.tool.schema.TargetType;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.jboss.logging.Logger;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
/**
* @author Andrea Boriero
*/
@RunWith(Parameterized.class)
@RequiresDialect(SQLServerDialect.class)
public class SchemaUpdateSQLServerTest extends BaseUnitTestCase {
private static final Logger log = Logger.getLogger( SchemaUpdateSQLServerTest.class );
@Parameterized.Parameters
public static Collection<String> parameters() {
return Arrays.asList(
new String[] {JdbcMetadaAccessStrategy.GROUPED.toString(), JdbcMetadaAccessStrategy.INDIVIDUALLY.toString()}
);
}
@Parameterized.Parameter
public String jdbcMetadataExtractorStrategy;
private File output;
private StandardServiceRegistry ssr;
private MetadataImplementor metadata;
@Before
public void setUp() throws IOException {
if(!SQLServerDialect.class.isAssignableFrom( Dialect.getDialect().getClass() )) {
return;
}
output = File.createTempFile( "update_script", ".sql" );
output.deleteOnExit();
ssr = new StandardServiceRegistryBuilder()
.applySetting( AvailableSettings.KEYWORD_AUTO_QUOTING_ENABLED, "true" )
.applySetting( AvailableSettings.HBM2DDL_JDBC_METADATA_EXTRACTOR_STRATEGY, jdbcMetadataExtractorStrategy )
.build();
try (Connection connection = ssr.getService( JdbcServices.class ).getBootstrapJdbcConnectionAccess().obtainConnection();
Statement statement = connection.createStatement()) {
connection.setAutoCommit( true );
statement.executeUpdate( "DROP DATABASE hibernate_orm_test_collation" );
}
catch (SQLException e) {
log.debug( e.getMessage() );
}
try (Connection connection = ssr.getService( JdbcServices.class ).getBootstrapJdbcConnectionAccess().obtainConnection();
Statement statement = connection.createStatement()) {
connection.setAutoCommit( true );
statement.executeUpdate( "CREATE DATABASE hibernate_orm_test_collation COLLATE Latin1_General_CS_AS" );
statement.executeUpdate( "ALTER DATABASE [hibernate_orm_test_collation] SET AUTO_CLOSE OFF " );
}
catch (SQLException e) {
log.debug( e.getMessage() );
}
final MetadataSources metadataSources = new MetadataSources( ssr );
metadataSources.addAnnotatedClass( LowercaseTableNameEntity.class );
metadataSources.addAnnotatedClass( TestEntity.class );
metadataSources.addAnnotatedClass( UppercaseTableNameEntity.class );
metadataSources.addAnnotatedClass( MixedCaseTableNameEntity.class );
metadataSources.addAnnotatedClass( Match.class );
metadataSources.addAnnotatedClass( InheritanceRootEntity.class );
metadataSources.addAnnotatedClass( InheritanceChildEntity.class );
metadataSources.addAnnotatedClass( InheritanceSecondChildEntity.class );
metadata = (MetadataImplementor) metadataSources.buildMetadata();
metadata.validate();
}
@After
public void tearsDown() {
if(!SQLServerDialect.class.isAssignableFrom( Dialect.getDialect().getClass() )) {
return;
}
new SchemaExport().setHaltOnError( true )
.setOutputFile( output.getAbsolutePath() )
.setFormat( false )
.drop( EnumSet.of( TargetType.DATABASE ), metadata );
StandardServiceRegistryBuilder.destroy( ssr );
}
@Test
public void testSchemaUpdateAndValidation() throws Exception {
if(!SQLServerDialect.class.isAssignableFrom( Dialect.getDialect().getClass() )) {
return;
}
new SchemaUpdate().setHaltOnError( true )
.execute( EnumSet.of( TargetType.DATABASE ), metadata );
new SchemaValidator().validate( metadata );
new SchemaUpdate().setHaltOnError( true )
.setOutputFile( output.getAbsolutePath() )
.setFormat( false )
.execute( EnumSet.of( TargetType.DATABASE, TargetType.SCRIPT ), metadata );
final String fileContent = new String( Files.readAllBytes( output.toPath() ) );
assertThat( "The update output file should be empty", fileContent, is( "" ) );
}
@Entity(name = "TestEntity")
@Table(name = "`testentity`", catalog = "hibernate_orm_test_collation", schema = "dbo")
public static class LowercaseTableNameEntity {
@Id
long id;
String field1;
@ManyToMany(mappedBy = "entities")
Set<TestEntity> entity1s;
}
@Entity(name = "TestEntity1")
@Table(name = "TestEntity1", catalog = "hibernate_orm_test_collation", schema = "dbo")
public static class TestEntity {
@Id
@Column(name = "`Id`")
long id;
String field1;
@ManyToMany
@JoinTable(catalog = "hibernate_orm_test_collation", schema = "dbo")
Set<LowercaseTableNameEntity> entities;
@OneToMany
@JoinColumn
private Set<UppercaseTableNameEntity> entitie2s;
@ManyToOne
private LowercaseTableNameEntity entity;
}
@Entity(name = "TestEntity2")
@Table(name = "`TESTENTITY`", catalog = "hibernate_orm_test_collation", schema = "dbo")
public static class UppercaseTableNameEntity {
@Id
long id;
String field1;
@ManyToOne
TestEntity testEntity;
@ManyToOne
@JoinColumn(foreignKey = @ForeignKey(name = "FK_mixedCase"))
MixedCaseTableNameEntity mixedCaseTableNameEntity;
}
@Entity(name = "TestEntity3")
@Table(name = "`TESTentity`", catalog = "hibernate_orm_test_collation", schema = "dbo",
indexes = {@Index(name = "index1", columnList = "`FieLd1`"), @Index(name = "Index2", columnList = "`FIELD_2`")})
public static class MixedCaseTableNameEntity {
@Id
long id;
@Column(name = "`FieLd1`")
String field1;
@Column(name = "`FIELD_2`")
String field2;
@Column(name = "`field_3`")
String field3;
String field4;
@OneToMany
@JoinColumn
private Set<Match> matches = new HashSet<>();
}
@Entity(name = "Match")
@Table(name = "Match", catalog = "hibernate_orm_test_collation", schema = "dbo")
public static class Match {
@Id
long id;
String match;
@ElementCollection
@CollectionTable(catalog = "hibernate_orm_test_collation", schema = "dbo")
private Map<Integer, Integer> timeline = new TreeMap<>();
}
@Entity(name = "InheritanceRootEntity")
@Table(name = "InheritanceRootEntity", catalog = "hibernate_orm_test_collation", schema = "dbo")
@Inheritance(strategy = InheritanceType.JOINED)
public static class InheritanceRootEntity {
@Id
protected Long id;
}
@Entity(name = "InheritanceChildEntity")
@Table(name = "InheritanceChildEntity", catalog = "hibernate_orm_test_collation", schema = "dbo")
@PrimaryKeyJoinColumn(name = "ID", foreignKey = @ForeignKey(name = "FK_ROOT"))
public static class InheritanceChildEntity extends InheritanceRootEntity {
}
@Entity(name = "InheritanceSecondChildEntity")
@Table(name = "InheritanceSecondChildEntity", catalog = "hibernate_orm_test_collation", schema = "dbo")
@PrimaryKeyJoinColumn(name = "ID")
public static class InheritanceSecondChildEntity extends InheritanceRootEntity {
@ManyToOne
@JoinColumn
public Match match;
}
}