HHH-9936 - Same Sequence is created and dropped multiple times

This commit is contained in:
Steve Ebersole 2015-07-31 15:43:00 -05:00
parent 923ecb8e2c
commit 067e892767
6 changed files with 301 additions and 6 deletions

View File

@ -9,6 +9,7 @@ package org.hibernate.boot.model.relational;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
@ -33,7 +34,7 @@ public class Database {
private final Map<Namespace.Name,Namespace> namespaceMap = new TreeMap<Namespace.Name, Namespace>();
private List<AuxiliaryDatabaseObject> auxiliaryDatabaseObjects;
private Map<String,AuxiliaryDatabaseObject> auxiliaryDatabaseObjects;
private List<InitCommand> initCommands;
public Database(MetadataBuildingOptions buildingOptions) {
@ -148,15 +149,15 @@ public class Database {
public void addAuxiliaryDatabaseObject(AuxiliaryDatabaseObject auxiliaryDatabaseObject) {
if ( auxiliaryDatabaseObjects == null ) {
auxiliaryDatabaseObjects = new ArrayList<AuxiliaryDatabaseObject>();
auxiliaryDatabaseObjects = new HashMap<String,AuxiliaryDatabaseObject>();
}
auxiliaryDatabaseObjects.add( auxiliaryDatabaseObject );
auxiliaryDatabaseObjects.put( auxiliaryDatabaseObject.getExportIdentifier(), auxiliaryDatabaseObject );
}
public Collection<AuxiliaryDatabaseObject> getAuxiliaryDatabaseObjects() {
return auxiliaryDatabaseObjects == null
? Collections.<AuxiliaryDatabaseObject>emptyList()
: auxiliaryDatabaseObjects;
: auxiliaryDatabaseObjects.values();
}
public Collection<InitCommand> getInitCommands() {

View File

@ -0,0 +1,47 @@
/*
* 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.boot.model.relational;
import java.util.Set;
/**
* Mainly this is used to support legacy sequence exporting.
*
* @author Steve Ebersole
*
* @see org.hibernate.id.SequenceGenerator
*/
public class NamedAuxiliaryDatabaseObject
extends SimpleAuxiliaryDatabaseObject
implements Exportable {
private final String name;
public NamedAuxiliaryDatabaseObject(
String name,
Namespace namespace,
String createString,
String dropString,
Set<String> dialectScopes) {
super( namespace, createString, dropString, dialectScopes );
this.name = name;
}
public NamedAuxiliaryDatabaseObject(
String name,
Namespace namespace,
String[] createStrings,
String[] dropStrings,
Set<String> dialectScopes) {
super( namespace, createStrings, dropStrings, dialectScopes );
this.name = name;
}
@Override
public String getExportIdentifier() {
return name;
}
}

View File

@ -17,10 +17,10 @@ import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.boot.model.naming.ObjectNameNormalizer;
import org.hibernate.boot.model.relational.Database;
import org.hibernate.boot.model.relational.NamedAuxiliaryDatabaseObject;
import org.hibernate.boot.model.relational.Namespace;
import org.hibernate.boot.model.relational.QualifiedName;
import org.hibernate.boot.model.relational.QualifiedNameParser;
import org.hibernate.boot.model.relational.SimpleAuxiliaryDatabaseObject;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.engine.spi.SessionImplementor;
@ -173,7 +173,8 @@ public class SequenceGenerator
);
database.addAuxiliaryDatabaseObject(
new SimpleAuxiliaryDatabaseObject(
new NamedAuxiliaryDatabaseObject(
qualifiedSequenceName.getObjectName().render(),
namespace,
sqlCreateStrings( database.getDialect() ),
sqlDropStrings( database.getDialect() ),

View File

@ -192,6 +192,7 @@ public class SchemaCreatorImpl implements SchemaCreator {
}
if ( auxiliaryDatabaseObject.appliesToDialect( dialect ) ) {
checkExportIdentifier( auxiliaryDatabaseObject, exportIdentifiers );
applySqlStrings(
targets,
dialect.getAuxiliaryDatabaseObjectExporter().getSqlCreateStrings(

View File

@ -0,0 +1,118 @@
/*
* 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.id.sequence;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.model.relational.AuxiliaryDatabaseObject;
import org.hibernate.boot.model.relational.Namespace;
import org.hibernate.boot.model.relational.Sequence;
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.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
/**
* @author Steve Ebersole
*/
public class LegacySequenceExportTest extends BaseUnitTestCase {
private StandardServiceRegistry ssr;
@Before
public void prepare() {
ssr = new StandardServiceRegistryBuilder()
.applySetting( AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, "false" )
.build();
}
@After
public void destroy() {
StandardServiceRegistryBuilder.destroy( ssr );
}
@Test
@TestForIssue( jiraKey = "HHH-9936" )
public void testMultipleUsesOfDefaultSequenceName() {
final MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr )
.addAnnotatedClass( Entity1.class )
.addAnnotatedClass( Entity2.class )
.buildMetadata();
metadata.validate();
int auxCount = 0;
for ( AuxiliaryDatabaseObject auxiliaryDatabaseObject : metadata.getDatabase().getAuxiliaryDatabaseObjects() ) {
auxCount++;
}
assertEquals( 1, auxCount );
}
@Test
@TestForIssue( jiraKey = "HHH-9936" )
public void testMultipleUsesOfExplicitSequenceName() {
final MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr )
.addAnnotatedClass( Entity3.class )
.addAnnotatedClass( Entity4.class )
.buildMetadata();
metadata.validate();
int auxCount = 0;
for ( AuxiliaryDatabaseObject auxiliaryDatabaseObject : metadata.getDatabase().getAuxiliaryDatabaseObjects() ) {
auxCount++;
}
assertEquals( 1, auxCount );
}
@Entity( name = "Entity1" )
@Table( name = "Entity1" )
public static class Entity1 {
@Id
@GeneratedValue( strategy = GenerationType.SEQUENCE )
public Integer id;
}
@Entity( name = "Entity2" )
@Table( name = "Entity2" )
public static class Entity2 {
@Id
@GeneratedValue( strategy = GenerationType.SEQUENCE )
public Integer id;
}
@Entity( name = "Entity3" )
@Table( name = "Entity3" )
public static class Entity3 {
@Id
@GeneratedValue( strategy = GenerationType.SEQUENCE )
@SequenceGenerator( name = "my_sequence" )
public Integer id;
}
@Entity( name = "Entity4" )
@Table( name = "Entity4" )
public static class Entity4 {
@Id
@GeneratedValue( strategy = GenerationType.SEQUENCE )
@SequenceGenerator( name = "my_sequence" )
public Integer id;
}
}

View File

@ -0,0 +1,127 @@
/*
* 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.id.sequence;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.model.relational.Namespace;
import org.hibernate.boot.model.relational.Sequence;
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.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
/**
* @author Steve Ebersole
*/
public class SequenceExportTest extends BaseUnitTestCase {
private StandardServiceRegistry ssr;
@Before
public void prepare() {
ssr = new StandardServiceRegistryBuilder()
.applySetting( AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, "true" )
.build();
}
@After
public void destroy() {
StandardServiceRegistryBuilder.destroy( ssr );
}
@Test
@TestForIssue( jiraKey = "HHH-9936" )
public void testMultipleUsesOfDefaultSequenceName() {
final MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr )
.addAnnotatedClass( Entity1.class )
.addAnnotatedClass( Entity2.class )
.buildMetadata();
metadata.validate();
int namespaceCount = 0;
int sequenceCount = 0;
for ( Namespace namespace : metadata.getDatabase().getNamespaces() ) {
namespaceCount++;
for ( Sequence sequence : namespace.getSequences() ) {
sequenceCount++;
}
}
assertEquals( 1, namespaceCount );
assertEquals( 1, sequenceCount );
}
@Test
@TestForIssue( jiraKey = "HHH-9936" )
public void testMultipleUsesOfExplicitSequenceName() {
final MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr )
.addAnnotatedClass( Entity3.class )
.addAnnotatedClass( Entity4.class )
.buildMetadata();
metadata.validate();
int namespaceCount = 0;
int sequenceCount = 0;
for ( Namespace namespace : metadata.getDatabase().getNamespaces() ) {
namespaceCount++;
for ( Sequence sequence : namespace.getSequences() ) {
sequenceCount++;
}
}
assertEquals( 1, namespaceCount );
assertEquals( 1, sequenceCount );
}
@Entity( name = "Entity1" )
@Table( name = "Entity1" )
public static class Entity1 {
@Id
@GeneratedValue( strategy = GenerationType.SEQUENCE )
public Integer id;
}
@Entity( name = "Entity2" )
@Table( name = "Entity2" )
public static class Entity2 {
@Id
@GeneratedValue( strategy = GenerationType.SEQUENCE )
public Integer id;
}
@Entity( name = "Entity3" )
@Table( name = "Entity3" )
public static class Entity3 {
@Id
@GeneratedValue( strategy = GenerationType.SEQUENCE )
@SequenceGenerator( name = "my_sequence" )
public Integer id;
}
@Entity( name = "Entity4" )
@Table( name = "Entity4" )
public static class Entity4 {
@Id
@GeneratedValue( strategy = GenerationType.SEQUENCE )
@SequenceGenerator( name = "my_sequence" )
public Integer id;
}
}