Skip to content

Commit

Permalink
HHH-9936 - Same Sequence is created and dropped multiple times
Browse files Browse the repository at this point in the history
  • Loading branch information
sebersole committed Aug 4, 2015
1 parent 6974744 commit 4183672
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 49 deletions.
Expand Up @@ -10,20 +10,20 @@
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.Properties;

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.Sequence;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.internal.log.DeprecationLogger;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.Type;
Expand Down Expand Up @@ -57,12 +57,14 @@ public class SequenceGenerator
/**
* The parameters parameter, appended to the create sequence DDL.
* For example (Oracle): <tt>INCREMENT BY 1 START WITH 1 MAXVALUE 100 NOCACHE</tt>.
*
* @deprecated No longer supported. To specify initial-value or increment use the
* org.hibernate.id.enhanced.SequenceStyleGenerator generator instead.
*/
public static final String PARAMETERS = "parameters";

private QualifiedName qualifiedSequenceName;
private QualifiedName logicalQualifiedSequenceName;
private String sequenceName;
private String parameters;
private Type identifierType;
private String sql;

Expand All @@ -81,20 +83,24 @@ public String getSequenceName() {
@Override
@SuppressWarnings("StatementWithEmptyBody")
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
DeprecationLogger.DEPRECATION_LOGGER.deprecatedSequenceGenerator( getClass().getName() );

identifierType = type;
parameters = params.getProperty( PARAMETERS );

final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class );
final Dialect dialect = jdbcEnvironment.getDialect();
final ObjectNameNormalizer normalizer = ( ObjectNameNormalizer ) params.get( IDENTIFIER_NORMALIZER );
qualifiedSequenceName = QualifiedNameParser.INSTANCE.parse(
logicalQualifiedSequenceName = QualifiedNameParser.INSTANCE.parse(
ConfigurationHelper.getString( SEQUENCE, params, "hibernate_sequence" ),
normalizer.normalizeIdentifierQuoting( params.getProperty( CATALOG ) ),
normalizer.normalizeIdentifierQuoting( params.getProperty( SCHEMA ) )
);
sequenceName = jdbcEnvironment.getQualifiedObjectNameFormatter().format( qualifiedSequenceName, dialect );

sql = dialect.getSequenceNextValString( sequenceName );
if ( params.containsKey( PARAMETERS ) ) {
LOG.warn(
"Use of 'parameters' config setting is no longer supported; " +
"to specify initial-value or increment use the " +
"org.hibernate.id.enhanced.SequenceStyleGenerator generator instead."
);
}
}

@Override
Expand Down Expand Up @@ -140,11 +146,7 @@ protected IntegralDataTypeHolder buildHolder() {
@Override
@SuppressWarnings( {"deprecation"})
public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
String[] ddl = dialect.getCreateSequenceStrings( sequenceName );
if ( parameters != null ) {
ddl[ddl.length - 1] += ' ' + parameters;
}
return ddl;
return dialect.getCreateSequenceStrings( sequenceName, 1, 1 );
}

@Override
Expand All @@ -164,22 +166,29 @@ public String determineBulkInsertionIdentifierGenerationSelectFragment(Dialect d

@Override
public void registerExportables(Database database) {
// we cannot register a proper Sequence object here because of the free-form
//'parameters' as opposed to specific initialValue/increment values

final Namespace namespace = database.locateNamespace(
qualifiedSequenceName.getCatalogName(),
qualifiedSequenceName.getSchemaName()
logicalQualifiedSequenceName.getCatalogName(),
logicalQualifiedSequenceName.getSchemaName()
);
Sequence sequence = namespace.locateSequence( logicalQualifiedSequenceName.getObjectName() );
if ( sequence != null ) {
sequence.validate( 1, 1 );
}
else {
sequence = namespace.createSequence(
logicalQualifiedSequenceName.getObjectName(),
1,
1
);
}

final JdbcEnvironment jdbcEnvironment = database.getJdbcEnvironment();
final Dialect dialect = jdbcEnvironment.getDialect();

database.addAuxiliaryDatabaseObject(
new NamedAuxiliaryDatabaseObject(
qualifiedSequenceName.getObjectName().render(),
namespace,
sqlCreateStrings( database.getDialect() ),
sqlDropStrings( database.getDialect() ),
Collections.<String>emptySet()
)
this.sequenceName = jdbcEnvironment.getQualifiedObjectNameFormatter().format(
sequence.getName(),
dialect
);
this.sql = jdbcEnvironment.getDialect().getSequenceNextValString( sequenceName );
}
}
Expand Up @@ -159,4 +159,13 @@ void recognizedObsoleteHibernateNamespace(
void connectionProviderClassDeprecated(
String providerClassName,
String actualProviderClassName);

@LogMessage(level = WARN)
@Message(
id = 90000014,
value = "Found use of deprecated [%s] sequence-based id generator; " +
"use org.hibernate.id.enhanced.SequenceStyleGenerator instead. " +
"See Hibernate Domain Model Mapping Guide for details."
)
void deprecatedSequenceGenerator(String generatorImpl);
}
Expand Up @@ -16,6 +16,7 @@
import org.hibernate.Session;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.ObjectNameNormalizer;
import org.hibernate.boot.model.relational.SimpleAuxiliaryDatabaseObject;
import org.hibernate.boot.registry.StandardServiceRegistry;
Expand All @@ -26,6 +27,7 @@
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.internal.SessionImpl;
import org.hibernate.jdbc.Work;
import org.hibernate.type.StandardBasicTypes;
Expand Down Expand Up @@ -55,7 +57,7 @@ public class SequenceHiLoGeneratorNoIncrementTest extends BaseUnitTestCase {

private StandardServiceRegistry serviceRegistry;
private SessionFactoryImplementor sessionFactory;
private SequenceHiLoGenerator generator;
private SequenceStyleGenerator generator;
private SessionImplementor session;

@Before
Expand All @@ -70,12 +72,13 @@ public void setUp() throws Exception {
.applySetting( AvailableSettings.HBM2DDL_AUTO, "create-drop" )
.build();

generator = new SequenceHiLoGenerator();
generator = new SequenceStyleGenerator();

// Build the properties used to configure the id generator
Properties properties = new Properties();
properties.setProperty( SequenceGenerator.SEQUENCE, TEST_SEQUENCE );
properties.setProperty( SequenceHiLoGenerator.MAX_LO, "0" ); // JPA allocationSize of 1
properties.setProperty( SequenceStyleGenerator.SEQUENCE_PARAM, TEST_SEQUENCE );
properties.setProperty( SequenceStyleGenerator.OPT_PARAM, "legacy-hilo" );
properties.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "0" ); // JPA allocationSize of 1
properties.put(
PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER,
new ObjectNameNormalizer() {
Expand All @@ -88,15 +91,7 @@ protected MetadataBuildingContext getBuildingContext() {
generator.configure( StandardBasicTypes.LONG, properties, serviceRegistry );

final Metadata metadata = new MetadataSources( serviceRegistry ).buildMetadata();
metadata.getDatabase().addAuxiliaryDatabaseObject(
new SimpleAuxiliaryDatabaseObject(
Collections.<String>emptySet(),
null,
null,
generator.sqlCreateStrings( TestingDatabaseInfo.DIALECT ),
generator.sqlDropStrings( TestingDatabaseInfo.DIALECT )
)
);
generator.registerExportables( metadata.getDatabase() );

sessionFactory = (SessionFactoryImplementor) metadata.buildSessionFactory();
}
Expand Down
Expand Up @@ -57,12 +57,16 @@ public void testMultipleUsesOfDefaultSequenceName() {
.buildMetadata();
metadata.validate();

int auxCount = 0;
for ( AuxiliaryDatabaseObject auxiliaryDatabaseObject : metadata.getDatabase().getAuxiliaryDatabaseObjects() ) {
auxCount++;
assertEquals( 0, metadata.getDatabase().getAuxiliaryDatabaseObjects().size() );

int count = 0;
for ( Namespace namespace : metadata.getDatabase().getNamespaces() ) {
for ( Sequence sequence : namespace.getSequences() ) {
count++;
}
}

assertEquals( 1, auxCount );
assertEquals( 1, count );
}

@Test
Expand All @@ -74,12 +78,16 @@ public void testMultipleUsesOfExplicitSequenceName() {
.buildMetadata();
metadata.validate();

int auxCount = 0;
for ( AuxiliaryDatabaseObject auxiliaryDatabaseObject : metadata.getDatabase().getAuxiliaryDatabaseObjects() ) {
auxCount++;
assertEquals( 0, metadata.getDatabase().getAuxiliaryDatabaseObjects().size() );

int count = 0;
for ( Namespace namespace : metadata.getDatabase().getNamespaces() ) {
for ( Sequence sequence : namespace.getSequences() ) {
count++;
}
}

assertEquals( 1, auxCount );
assertEquals( 1, count );
}

@Entity( name = "Entity1" )
Expand Down

0 comments on commit 4183672

Please sign in to comment.