HHH-12973 - Inconsistent identity generation when using the default @SequenceGenerator with a database sequence having the increment size of 1

This commit is contained in:
Vlad Mihalcea 2018-09-17 17:59:53 +03:00
parent ec21c6df5e
commit 1db476dbd5
58 changed files with 2246 additions and 128 deletions

View File

@ -1961,4 +1961,19 @@ public interface AvailableSettings extends org.hibernate.jpa.AvailableSettings {
*/
String QUERY_STATISTICS_MAX_SIZE = "hibernate.statistics.query_max_size";
/**
* This setting defines the {@link org.hibernate.id.SequenceMismatchStrategy} used when
* Hibernate detects a mismatch between a sequence configuration in an entity mapping
* and its database sequence object counterpart.
* </p>
* Possible values are {@link org.hibernate.id.SequenceMismatchStrategy#EXCEPTION},
* {@link org.hibernate.id.SequenceMismatchStrategy#LOG}, and
* {@link org.hibernate.id.SequenceMismatchStrategy#FIX}.
* </p>
* The default value is given by the {@link org.hibernate.id.SequenceMismatchStrategy#EXCEPTION},
* meaning that an Exception is thrown when detecting such a conflict.
*
* @since 5.4
*/
String SEQUENCE_INCREMENT_SIZE_MISMATCH_STRATEGY = "hibernate.id.sequence.increment_size_mismatch_strategy";
}

View File

@ -79,6 +79,8 @@ import org.hibernate.mapping.Table;
import org.hibernate.procedure.internal.StandardCallableStatementSupport;
import org.hibernate.procedure.spi.CallableStatementSupport;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorHANADatabaseImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.tool.schema.internal.StandardTableExporter;
import org.hibernate.tool.schema.spi.Exporter;
import org.hibernate.type.StandardBasicTypes;
@ -1108,7 +1110,12 @@ public abstract class AbstractHANADialect extends Dialect {
@Override
public String getQuerySequencesString() {
return "select sequence_name from sys.sequences";
return "select * from sys.sequences";
}
@Override
public SequenceInformationExtractor getSequenceInformationExtractor() {
return SequenceInformationExtractorHANADatabaseImpl.INSTANCE;
}
@Override
@ -1636,5 +1643,4 @@ public abstract class AbstractHANADialect extends Dialect {
public boolean supportsNoWait() {
return true;
}
}

View File

@ -16,6 +16,8 @@ import org.hibernate.dialect.identity.CUBRIDIdentityColumnSupport;
import org.hibernate.dialect.identity.IdentityColumnSupport;
import org.hibernate.dialect.pagination.CUBRIDLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorCUBRIDDatabaseImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.StandardBasicTypes;
/**
@ -284,7 +286,12 @@ public class CUBRIDDialect extends Dialect {
@Override
public String getQuerySequencesString() {
return "select name from db_serial";
return "select * from db_serial";
}
@Override
public SequenceInformationExtractor getSequenceInformationExtractor() {
return SequenceInformationExtractorCUBRIDDatabaseImpl.INSTANCE;
}
@Override

View File

@ -32,6 +32,6 @@ public class DB2390V8Dialect extends DB2390Dialect {
}
public String getQuerySequencesString() {
return "select name from sysibm.syssequences";
return "select * from sysibm.syssequences";
}
}

View File

@ -33,12 +33,14 @@ import org.hibernate.exception.LockTimeoutException;
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
import org.hibernate.hql.spi.id.IdTableSupportStandardImpl;
import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
import org.hibernate.hql.spi.id.global.GlobalTemporaryTableBulkIdStrategy;
import org.hibernate.hql.spi.id.local.AfterUseAction;
import org.hibernate.hql.spi.id.local.LocalTemporaryTableBulkIdStrategy;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.JdbcExceptionHelper;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorDB2DatabaseImpl;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNoOpImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.sql.DecimalTypeDescriptor;
import org.hibernate.type.descriptor.sql.SmallIntTypeDescriptor;
@ -267,7 +269,17 @@ public class DB2Dialect extends Dialect {
@Override
public String getQuerySequencesString() {
return "select seqname from sysibm.syssequences";
return "select * from syscat.sequences";
}
@Override
public SequenceInformationExtractor getSequenceInformationExtractor() {
if ( getQuerySequencesString() == null ) {
return SequenceInformationExtractorNoOpImpl.INSTANCE;
}
else {
return SequenceInformationExtractorDB2DatabaseImpl.INSTANCE;
}
}
@Override

View File

@ -29,6 +29,9 @@ import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.sql.CaseFragment;
import org.hibernate.sql.DerbyCaseFragment;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorDerbyDatabaseImpl;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNoOpImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.jboss.logging.Logger;
@ -130,13 +133,23 @@ public class DerbyDialect extends DB2Dialect {
@Override
public String getQuerySequencesString() {
if ( supportsSequences() ) {
return "select SEQUENCENAME from SYS.SYSSEQUENCES";
return "select sys.sysschemas.schemaname as sequence_schema, sys.syssequences.* from sys.syssequences left join sys.sysschemas on sys.syssequences.schemaid = sys.sysschemas.schemaid";
}
else {
return null;
}
}
@Override
public SequenceInformationExtractor getSequenceInformationExtractor() {
if ( getQuerySequencesString() == null ) {
return SequenceInformationExtractorNoOpImpl.INSTANCE;
}
else {
return SequenceInformationExtractorDerbyDatabaseImpl.INSTANCE;
}
}
@Override
public String getSequenceNextValString(String sequenceName) {
if ( supportsSequences() ) {

View File

@ -37,7 +37,7 @@ import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.JdbcExceptionHelper;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorH2DatabaseImpl;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNoOpImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.StandardBasicTypes;
@ -81,18 +81,15 @@ public class H2Dialect extends Dialect {
public H2Dialect() {
super();
String querySequenceString = "select sequence_name from information_schema.sequences";
SequenceInformationExtractor sequenceInformationExtractor = SequenceInformationExtractorH2DatabaseImpl.INSTANCE;
int buildId = Integer.MIN_VALUE;
try {
// HHH-2300
final Class h2ConstantsClass = ReflectHelper.classForName( "org.h2.engine.Constants" );
final int majorVersion = (Integer) h2ConstantsClass.getDeclaredField( "VERSION_MAJOR" ).get( null );
final int minorVersion = (Integer) h2ConstantsClass.getDeclaredField( "VERSION_MINOR" ).get( null );
final int buildId = (Integer) h2ConstantsClass.getDeclaredField( "BUILD_ID" ).get( null );
if ( buildId < 32 ) {
querySequenceString = "select name from information_schema.sequences";
sequenceInformationExtractor = SequenceInformationExtractorLegacyImpl.INSTANCE;
}
buildId = (Integer) h2ConstantsClass.getDeclaredField( "BUILD_ID" ).get( null );
if ( ! ( majorVersion > 1 || minorVersion > 2 || buildId >= 139 ) ) {
LOG.unsupportedMultiTableBulkHqlJpaql( majorVersion, minorVersion, buildId );
}
@ -103,8 +100,14 @@ public class H2Dialect extends Dialect {
LOG.undeterminedH2Version();
}
this.querySequenceString = querySequenceString;
this.sequenceInformationExtractor = sequenceInformationExtractor;
if ( buildId >= 32 ) {
this.sequenceInformationExtractor = SequenceInformationExtractorH2DatabaseImpl.INSTANCE;
this.querySequenceString = "select * from information_schema.sequences";
}
else {
this.sequenceInformationExtractor = SequenceInformationExtractorNoOpImpl.INSTANCE;
this.querySequenceString = null;
}
registerColumnType( Types.BOOLEAN, "boolean" );
registerColumnType( Types.BIGINT, "bigint" );

View File

@ -7,6 +7,7 @@
package org.hibernate.dialect;
import java.io.Serializable;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Locale;
@ -48,10 +49,12 @@ import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.JdbcExceptionHelper;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.persister.entity.Lockable;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorHANADatabaseImpl;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorHSQLDBDatabaseImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.StandardBasicTypes;
import org.jboss.logging.Logger;
import java.sql.DatabaseMetaData;
/**
* An SQL dialect compatible with HSQLDB (HyperSQL).
@ -369,7 +372,12 @@ public class HSQLDialect extends Dialect {
@Override
public String getQuerySequencesString() {
// this assumes schema support, which is present in 1.8.0 and later...
return "select sequence_name from information_schema.system_sequences";
return "select * from information_schema.sequences";
}
@Override
public SequenceInformationExtractor getSequenceInformationExtractor() {
return SequenceInformationExtractorHSQLDBDatabaseImpl.INSTANCE;
}
@Override

View File

@ -28,6 +28,8 @@ import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
import org.hibernate.hql.spi.id.local.AfterUseAction;
import org.hibernate.hql.spi.id.local.LocalTemporaryTableBulkIdStrategy;
import org.hibernate.internal.util.JdbcExceptionHelper;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorInformixDatabaseImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.StandardBasicTypes;
/**
@ -148,7 +150,7 @@ public class InformixDialect extends Dialect {
@Override
public String getDropSequenceString(String sequenceName) {
return "drop sequence " + sequenceName + " restrict";
return "drop sequence " + sequenceName;
}
@Override
@ -173,7 +175,12 @@ public class InformixDialect extends Dialect {
@Override
public String getQuerySequencesString() {
return "select tabname from informix.systables where tabtype='Q'";
return "select systables.tabname as sequence_name, syssequences.* from syssequences join systables on syssequences.tabid = systables.tabid where tabtype = 'Q'";
}
@Override
public SequenceInformationExtractor getSequenceInformationExtractor() {
return SequenceInformationExtractorInformixDatabaseImpl.INSTANCE;
}
@Override

View File

@ -16,6 +16,8 @@ import org.hibernate.dialect.pagination.AbstractLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.LimitHelper;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorIngresDatabaseImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.StandardBasicTypes;
/**

View File

@ -20,6 +20,8 @@ import org.hibernate.hql.spi.id.IdTableSupportStandardImpl;
import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
import org.hibernate.hql.spi.id.global.GlobalTemporaryTableBulkIdStrategy;
import org.hibernate.hql.spi.id.local.AfterUseAction;
import org.hibernate.tool.schema.extract.internal.SequenceNameExtractorImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.StandardBasicTypes;
/**
@ -215,6 +217,11 @@ public class IngresDialect extends Dialect {
return "select seq_name from iisequence";
}
@Override
public SequenceInformationExtractor getSequenceInformationExtractor() {
return SequenceNameExtractorImpl.INSTANCE;
}
@Override
public String getLowercaseFunction() {
return "lowercase";

View File

@ -5,6 +5,7 @@
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.dialect;
import java.sql.Types;
import java.util.Locale;
@ -15,6 +16,8 @@ import org.hibernate.dialect.pagination.AbstractLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.LimitHelper;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.tool.schema.extract.internal.SequenceNameExtractorImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.StandardBasicTypes;
/**
@ -97,6 +100,11 @@ public class InterbaseDialect extends Dialect {
return "select RDB$GENERATOR_NAME from RDB$GENERATORS";
}
@Override
public SequenceInformationExtractor getSequenceInformationExtractor() {
return SequenceNameExtractorImpl.INSTANCE;
}
@Override
public String getForUpdateString() {
return " with lock";

View File

@ -9,6 +9,8 @@ package org.hibernate.dialect;
import org.hibernate.LockOptions;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.tool.schema.extract.internal.SequenceNameExtractorImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.StandardBasicTypes;
/**
@ -59,6 +61,12 @@ public class MariaDB103Dialect extends MariaDB102Dialect {
return "select table_name from information_schema.TABLES where table_type='SEQUENCE'";
}
@Override
public SequenceInformationExtractor getSequenceInformationExtractor() {
//TODO: Future improvement - https://hibernate.atlassian.net/browse/HHH-13008
return SequenceNameExtractorImpl.INSTANCE;
}
@Override
public String getWriteLockString(int timeout) {
if ( timeout == LockOptions.NO_WAIT ) {

View File

@ -12,6 +12,8 @@ import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.identity.IdentityColumnSupport;
import org.hibernate.dialect.identity.MimerSQLIdentityColumnSupport;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorMimerSQLDatabaseImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.StandardBasicTypes;
/**
@ -166,7 +168,12 @@ public class MimerSQLDialect extends Dialect {
@Override
public String getQuerySequencesString() {
return "select sequence_schema || '.' || sequence_name from information_schema.ext_sequences";
return "select * from information_schema.ext_sequences";
}
@Override
public SequenceInformationExtractor getSequenceInformationExtractor() {
return SequenceInformationExtractorMimerSQLDatabaseImpl.INSTANCE;
}
@Override

View File

@ -10,7 +10,6 @@ import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -45,6 +44,8 @@ import org.hibernate.sql.CaseFragment;
import org.hibernate.sql.DecodeCaseFragment;
import org.hibernate.sql.JoinFragment;
import org.hibernate.sql.OracleJoinFragment;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorOracleDatabaseImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.sql.BitTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
@ -489,12 +490,11 @@ public class Oracle8iDialect extends Dialect {
@Override
public String getQuerySequencesString() {
return " select sequence_name from all_sequences"
+ " union"
+ " select synonym_name"
+ " from all_synonyms us, all_sequences asq"
+ " where asq.sequence_name = us.table_name"
+ " and asq.sequence_owner = us.table_owner";
return "select * from all_sequences";
}
public SequenceInformationExtractor getSequenceInformationExtractor() {
return SequenceInformationExtractorOracleDatabaseImpl.INSTANCE;
}
@Override

View File

@ -20,6 +20,8 @@ import org.hibernate.hql.spi.id.global.GlobalTemporaryTableBulkIdStrategy;
import org.hibernate.hql.spi.id.local.AfterUseAction;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.JdbcExceptionHelper;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorOracleDatabaseImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.StandardBasicTypes;
import org.jboss.logging.Logger;
@ -284,7 +286,11 @@ public class Oracle9Dialect extends Dialect {
@Override
public String getQuerySequencesString() {
return "select sequence_name from user_sequences";
return "select * from all_sequences";
}
public SequenceInformationExtractor getSequenceInformationExtractor() {
return SequenceInformationExtractorOracleDatabaseImpl.INSTANCE;
}
@Override

View File

@ -242,7 +242,7 @@ public class PostgreSQL81Dialect extends Dialect {
@Override
public String getQuerySequencesString() {
return "select relname from pg_class where relkind='S'";
return "select * from information_schema.sequences";
}
@Override

View File

@ -19,6 +19,8 @@ import org.hibernate.hql.spi.id.local.AfterUseAction;
import org.hibernate.hql.spi.id.local.LocalTemporaryTableBulkIdStrategy;
import org.hibernate.sql.CaseFragment;
import org.hibernate.sql.DecodeCaseFragment;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorSAPDBDatabaseImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.StandardBasicTypes;
/**
@ -198,7 +200,12 @@ public class SAPDBDialect extends Dialect {
@Override
public String getQuerySequencesString() {
return "select sequence_name from domain.sequences";
return "select * from domain.sequences";
}
@Override
public SequenceInformationExtractor getSequenceInformationExtractor() {
return SequenceInformationExtractorSAPDBDatabaseImpl.INSTANCE;
}
@Override

View File

@ -6,8 +6,6 @@
*/
package org.hibernate.dialect;
import java.util.List;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.SQLServer2012LimitHandler;
@ -50,7 +48,7 @@ public class SQLServer2012Dialect extends SQLServer2008Dialect {
@Override
public String getQuerySequencesString() {
return "select name from sys.sequences";
return "select * from information_schema.sequences";
}
@Override

View File

@ -30,6 +30,8 @@ import org.hibernate.hql.spi.id.local.AfterUseAction;
import org.hibernate.persister.entity.Lockable;
import org.hibernate.sql.JoinFragment;
import org.hibernate.sql.OracleJoinFragment;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorTimesTenDatabaseImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.StandardBasicTypes;
/**
@ -129,7 +131,12 @@ public class TimesTenDialect extends Dialect {
@Override
public String getQuerySequencesString() {
return "select NAME from sys.sequences";
return "select * from sys.sequences";
}
@Override
public SequenceInformationExtractor getSequenceInformationExtractor() {
return SequenceInformationExtractorTimesTenDatabaseImpl.INSTANCE;
}
@Override

View File

@ -13,6 +13,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.hibernate.engine.jdbc.cursor.internal.StandardRefCursorSupport;
@ -21,6 +22,7 @@ import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.engine.jdbc.env.spi.SQLStateType;
import org.hibernate.engine.jdbc.spi.TypeInfo;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.tool.schema.extract.spi.SequenceInformation;
/**
* Standard implementation of ExtractedDatabaseMetaData
@ -45,6 +47,7 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
private final Set<String> extraKeywords;
private final LinkedHashSet<TypeInfo> typeInfoSet;
private final List<SequenceInformation> sequenceInformationList;
private ExtractedDatabaseMetaDataImpl(
JdbcEnvironment jdbcEnvironment,
@ -60,7 +63,8 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
boolean supportsDataDefinitionInTransaction,
boolean doesDataDefinitionCauseTransactionCommit,
SQLStateType sqlStateType,
boolean lobLocatorUpdateCopy) {
boolean lobLocatorUpdateCopy,
List<SequenceInformation> sequenceInformationList) {
this.jdbcEnvironment = jdbcEnvironment;
this.connectionCatalogName = connectionCatalogName;
@ -82,6 +86,7 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
this.doesDataDefinitionCauseTransactionCommit = doesDataDefinitionCauseTransactionCommit;
this.sqlStateType = sqlStateType;
this.lobLocatorUpdateCopy = lobLocatorUpdateCopy;
this.sequenceInformationList = sequenceInformationList;
}
@Override
@ -154,6 +159,11 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
return typeInfoSet;
}
@Override
public List<SequenceInformation> getSequenceInformationList() {
return sequenceInformationList;
}
public static class Builder {
private final JdbcEnvironment jdbcEnvironment;
@ -172,6 +182,7 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
private boolean doesDataDefinitionCauseTransactionCommit;
private SQLStateType sqlStateType;
private boolean lobLocatorUpdateCopy;
private List<SequenceInformation> sequenceInformationList = Collections.emptyList();
public Builder(JdbcEnvironment jdbcEnvironment) {
this.jdbcEnvironment = jdbcEnvironment;
@ -296,6 +307,11 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
return this;
}
public Builder setSequenceInformationList(List<SequenceInformation> sequenceInformationList) {
this.sequenceInformationList = sequenceInformationList;
return this;
}
public ExtractedDatabaseMetaDataImpl build() {
return new ExtractedDatabaseMetaDataImpl(
jdbcEnvironment,
@ -311,7 +327,8 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
supportsDataDefinitionInTransaction,
doesDataDefinitionCauseTransactionCommit,
sqlStateType,
lobLocatorUpdateCopy
lobLocatorUpdateCopy,
sequenceInformationList
);
}
}

View File

@ -6,12 +6,17 @@
*/
package org.hibernate.engine.jdbc.env.internal;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.registry.selector.spi.StrategySelector;
@ -34,6 +39,8 @@ import org.hibernate.exception.internal.SQLStateConversionDelegate;
import org.hibernate.exception.internal.StandardSQLExceptionConverter;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.tool.schema.extract.spi.ExtractionContext;
import org.hibernate.tool.schema.extract.spi.SequenceInformation;
import org.jboss.logging.Logger;
@ -62,7 +69,7 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
* @param serviceRegistry The service registry
* @param dialect The resolved dialect.
*/
public JdbcEnvironmentImpl(ServiceRegistryImplementor serviceRegistry, Dialect dialect) {
public JdbcEnvironmentImpl(final ServiceRegistryImplementor serviceRegistry, Dialect dialect) {
this.dialect = dialect;
final ConfigurationService cfgService = serviceRegistry.getService( ConfigurationService.class );
@ -78,7 +85,8 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
final IdentifierHelperBuilder identifierHelperBuilder = IdentifierHelperBuilder.from( this );
identifierHelperBuilder.setGloballyQuoteIdentifiers( globalQuoting( cfgService ) );
identifierHelperBuilder.setSkipGlobalQuotingForColumnDefinitions( globalQuotingSkippedForColumnDefinitions( cfgService ) );
identifierHelperBuilder.setSkipGlobalQuotingForColumnDefinitions( globalQuotingSkippedForColumnDefinitions(
cfgService ) );
identifierHelperBuilder.setAutoQuoteKeywords( autoKeywordQuoting( cfgService ) );
identifierHelperBuilder.setNameQualifierSupport( nameQualifierSupport );
@ -153,11 +161,6 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
this.sqlExceptionHelper = buildSqlExceptionHelper( dialect, false );
this.extractedMetaDataSupport = new ExtractedDatabaseMetaDataImpl.Builder( this )
.apply( databaseMetaData )
.setSupportsNamedParameters( databaseMetaData.supportsNamedParameters() )
.build();
NameQualifierSupport nameQualifierSupport = dialect.getNameQualifierSupport();
if ( nameQualifierSupport == null ) {
nameQualifierSupport = determineNameQualifierSupport( databaseMetaData );
@ -179,6 +182,12 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
}
this.identifierHelper = identifierHelper;
this.extractedMetaDataSupport = new ExtractedDatabaseMetaDataImpl.Builder( this )
.apply( databaseMetaData )
.setSupportsNamedParameters( databaseMetaData.supportsNamedParameters() )
.setSequenceInformationList( sequenceInformationList( databaseMetaData.getConnection() ) )
.build();
this.currentCatalog = null;
this.currentSchema = null;
@ -227,12 +236,6 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
this.sqlExceptionHelper = buildSqlExceptionHelper( dialect, logWarnings( cfgService, dialect ) );
this.extractedMetaDataSupport = new ExtractedDatabaseMetaDataImpl.Builder( this )
.apply( databaseMetaData )
.setConnectionSchemaName( determineCurrentSchemaName( databaseMetaData, serviceRegistry, dialect ) )
.setSupportsNamedParameters(dialect.supportsNamedParameters(databaseMetaData))
.build();
NameQualifierSupport nameQualifierSupport = dialect.getNameQualifierSupport();
if ( nameQualifierSupport == null ) {
nameQualifierSupport = determineNameQualifierSupport( databaseMetaData );
@ -241,7 +244,8 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
final IdentifierHelperBuilder identifierHelperBuilder = IdentifierHelperBuilder.from( this );
identifierHelperBuilder.setGloballyQuoteIdentifiers( globalQuoting( cfgService ) );
identifierHelperBuilder.setSkipGlobalQuotingForColumnDefinitions( globalQuotingSkippedForColumnDefinitions( cfgService ) );
identifierHelperBuilder.setSkipGlobalQuotingForColumnDefinitions( globalQuotingSkippedForColumnDefinitions(
cfgService ) );
identifierHelperBuilder.setAutoQuoteKeywords( autoKeywordQuoting( cfgService ) );
identifierHelperBuilder.setNameQualifierSupport( nameQualifierSupport );
IdentifierHelper identifierHelper = null;
@ -257,6 +261,13 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
}
this.identifierHelper = identifierHelper;
this.extractedMetaDataSupport = new ExtractedDatabaseMetaDataImpl.Builder( this )
.apply( databaseMetaData )
.setConnectionSchemaName( determineCurrentSchemaName( databaseMetaData, serviceRegistry, dialect ) )
.setSupportsNamedParameters( dialect.supportsNamedParameters( databaseMetaData ) )
.setSequenceInformationList( sequenceInformationList( databaseMetaData.getConnection() ) )
.build();
// and that current-catalog and current-schema happen after it
this.currentCatalog = identifierHelper.toIdentifier( extractedMetaDataSupport.getConnectionCatalogName() );
this.currentSchema = identifierHelper.toIdentifier( extractedMetaDataSupport.getConnectionSchemaName() );
@ -282,7 +293,8 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
Dialect dialect) throws SQLException {
final SchemaNameResolver schemaNameResolver;
final Object setting = serviceRegistry.getService( ConfigurationService.class ).getSettings().get( SCHEMA_NAME_RESOLVER );
final Object setting = serviceRegistry.getService( ConfigurationService.class ).getSettings().get(
SCHEMA_NAME_RESOLVER );
if ( setting == null ) {
schemaNameResolver = dialect.getSchemaNameResolver();
}
@ -375,4 +387,38 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
}
return null;
}
/**
* Get the sequence information List from the database.
*
* @param connection database connection
* @return sequence information List
*/
private List<SequenceInformation> sequenceInformationList(final Connection connection) {
try {
Iterable<SequenceInformation> sequenceInformationIterable = dialect
.getSequenceInformationExtractor()
.extractMetadata( new ExtractionContext.EmptyExtractionContext() {
@Override
public Connection getJdbcConnection() {
return connection;
}
@Override
public JdbcEnvironment getJdbcEnvironment() {
return JdbcEnvironmentImpl.this;
}
}
);
return StreamSupport.stream( sequenceInformationIterable.spliterator(), false )
.collect( Collectors.toList() );
}
catch (SQLException e) {
log.error( "Could not fetch the SequenceInformation from the database", e );
}
return Collections.emptyList();
}
}

View File

@ -6,10 +6,14 @@
*/
package org.hibernate.engine.jdbc.env.spi;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.hibernate.engine.jdbc.spi.TypeInfo;
import org.hibernate.tool.schema.extract.spi.SequenceInformation;
/**
* Information extracted from {@link java.sql.DatabaseMetaData} regarding what the JDBC driver reports as
@ -140,4 +144,13 @@ public interface ExtractedDatabaseMetaData {
* @see java.sql.DatabaseMetaData#locatorsUpdateCopy()
*/
boolean doesLobLocatorUpdateCopy();
/**
* Retrieve the list of {@code SequenceInformation} objects which describe the underlying database sequences.
*
* @return {@code SequenceInformation} objects.
*/
default List<SequenceInformation> getSequenceInformationList() {
return Collections.emptyList();
}
}

View File

@ -0,0 +1,68 @@
/*
* 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.id;
import org.hibernate.HibernateException;
/**
* Describes the strategy for handling the mismatch between a database sequence configuration and
* the one defined by the entity mapping.
*
* @author Vlad Mihalcea
*/
public enum SequenceMismatchStrategy {
/**
* When detecting a mismatch, Hibernate simply logs the sequence whose entity mapping configuration conflicts
* with the one found in the database.
*/
LOG,
/**
* When detecting a mismatch, Hibernate throws a {@link org.hibernate.MappingException} indicating the sequence
* whose entity mapping configuration conflict with the one found in the database.
*/
EXCEPTION,
/**
* When detecting a mismatch, Hibernate tries to fix it by overriding the entity sequence mapping using the one
* found in the database.
*/
FIX;
/**
* Interpret the configured SequenceMismatchStrategy value.
* <p>
* Valid values are either a {@link SequenceMismatchStrategy} object or its String representation.
* <p>
* For string values, the matching is case insensitive, so you can use either {@code FIX} or {@code fix}.
*
* @param sequenceMismatchStrategy configured {@link SequenceMismatchStrategy} representation
*
* @return associated {@link SequenceMismatchStrategy} object
*/
public static SequenceMismatchStrategy interpret(Object sequenceMismatchStrategy) {
if ( sequenceMismatchStrategy == null ) {
return EXCEPTION;
}
else if ( sequenceMismatchStrategy instanceof SequenceMismatchStrategy ) {
return (SequenceMismatchStrategy) sequenceMismatchStrategy;
}
else if ( sequenceMismatchStrategy instanceof String ) {
String sequenceMismatchStrategyString = (String) sequenceMismatchStrategy;
for ( SequenceMismatchStrategy value : values() ) {
if ( value.name().equalsIgnoreCase( sequenceMismatchStrategyString ) ) {
return value;
}
}
}
throw new HibernateException(
"Unrecognized sequence.increment_size_mismatch_strategy value : [" + sequenceMismatchStrategy
+ "]. Supported values include [log], [exception], and [fix]."
);
}
}

View File

@ -25,10 +25,12 @@ import org.hibernate.id.BulkInsertionCapableIdentifierGenerator;
import org.hibernate.id.Configurable;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.id.SequenceMismatchStrategy;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.tool.schema.extract.spi.SequenceInformation;
import org.hibernate.type.Type;
import org.jboss.logging.Logger;
@ -218,12 +220,13 @@ public class SequenceStyleGenerator
}
// Configurable implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class );
final ConfigurationService configurationService = serviceRegistry.getService( ConfigurationService.class );
final Dialect dialect = jdbcEnvironment.getDialect();
this.identifierType = type;
@ -234,6 +237,37 @@ public class SequenceStyleGenerator
final int initialValue = determineInitialValue( params );
int incrementSize = determineIncrementSize( params );
if ( isPhysicalSequence( jdbcEnvironment, forceTableUse ) ) {
String databaseSequenceName = sequenceName.getObjectName().getText();
Long databaseIncrementValue = getSequenceIncrementValue( jdbcEnvironment, databaseSequenceName );
if ( databaseIncrementValue != null && !databaseIncrementValue.equals( (long) incrementSize ) ) {
int dbIncrementValue = databaseIncrementValue.intValue();
SequenceMismatchStrategy sequenceMismatchStrategy = configurationService.getSetting(
AvailableSettings.SEQUENCE_INCREMENT_SIZE_MISMATCH_STRATEGY,
SequenceMismatchStrategy::interpret,
SequenceMismatchStrategy.EXCEPTION
);
switch ( sequenceMismatchStrategy ) {
case EXCEPTION:
throw new MappingException(
String.format(
"The increment size of the [%s] sequence is set to [%d] in the entity mapping " +
"while the associated database sequence increment size is [%d].",
databaseSequenceName, incrementSize, dbIncrementValue
)
);
case FIX:
incrementSize = dbIncrementValue;
case LOG:
LOG.sequenceIncrementSizeMismatch( databaseSequenceName, incrementSize, dbIncrementValue );
break;
}
}
}
final String optimizationStrategy = determineOptimizationStrategy( params, incrementSize );
incrementSize = determineAdjustedIncrementSize( optimizationStrategy, incrementSize );
@ -443,8 +477,7 @@ public class SequenceStyleGenerator
QualifiedName sequenceName,
int initialValue,
int incrementSize) {
final boolean useSequence = jdbcEnvironment.getDialect().supportsSequences() && !forceTableUse;
if ( useSequence ) {
if ( isPhysicalSequence( jdbcEnvironment, forceTableUse ) ) {
return buildSequenceStructure( type, params, jdbcEnvironment, sequenceName, initialValue, incrementSize );
}
else {
@ -452,6 +485,10 @@ public class SequenceStyleGenerator
}
}
protected boolean isPhysicalSequence(JdbcEnvironment jdbcEnvironment, boolean forceTableUse) {
return jdbcEnvironment.getDialect().supportsSequences() && !forceTableUse;
}
protected DatabaseStructure buildSequenceStructure(
Type type,
Properties params,
@ -521,4 +558,24 @@ public class SequenceStyleGenerator
public void registerExportables(Database database) {
databaseStructure.registerExportables( database );
}
/**
* Get the database sequence increment value from the associated {@link SequenceInformation} object.
*
* @param jdbcEnvironment the current JdbcEnvironment
* @param sequenceName sequence name
*
* @return sequence increment value
*/
private Long getSequenceIncrementValue(JdbcEnvironment jdbcEnvironment, String sequenceName) {
return jdbcEnvironment.getExtractedDatabaseMetaData().getSequenceInformationList().stream().filter(
sequenceInformation -> {
Identifier catalog = sequenceInformation.getSequenceName().getCatalogName();
Identifier schema = sequenceInformation.getSequenceName().getSchemaName();
return sequenceName.equalsIgnoreCase( sequenceInformation.getSequenceName().getSequenceName().getText() ) &&
( catalog == null || catalog.equals( jdbcEnvironment.getCurrentCatalog() ) ) &&
( schema == null || schema.equals( jdbcEnvironment.getCurrentSchema() ) );
}
).map( SequenceInformation::getIncrementValue ).findFirst().orElse( null );
}
}

View File

@ -1843,4 +1843,8 @@ public interface CoreMessageLogger extends BasicLogger {
@LogMessage(level = WARN)
@Message(value = "Detaching an uninitialized collection with queued operations from a session: %s", id = 496)
void queuedOperationWhenDetachFromSession(String collectionInfoString);
@LogMessage(level = WARN)
@Message(value = "The increment size of the [%s] sequence is set to [%d] in the entity mapping while the associated database sequence increment size is [%d]. The database sequence increment size will take precedence to avoid identifier allocation conflicts.", id = 497)
void sequenceIncrementSizeMismatch(String sequenceName, int incrementSize, int databaseIncrementSize);
}

View File

@ -0,0 +1,55 @@
/*
* 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.tool.schema.extract.internal;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* @author Vlad Mihalcea
*/
public class SequenceInformationExtractorCUBRIDDatabaseImpl extends SequenceInformationExtractorLegacyImpl {
/**
* Singleton access
*/
public static final SequenceInformationExtractorCUBRIDDatabaseImpl INSTANCE = new SequenceInformationExtractorCUBRIDDatabaseImpl();
@Override
protected String sequenceNameColumn() {
return "name";
}
@Override
protected String sequenceCatalogColumn() {
return null;
}
@Override
protected String sequenceSchemaColumn() {
return null;
}
@Override
protected String sequenceStartValueColumn() {
return "started";
}
@Override
protected String sequenceMinValueColumn() {
return "min_val";
}
@Override
protected String sequenceMaxValueColumn() {
return "max_val";
}
@Override
protected String sequenceIncrementColumn() {
return "increment_val";
}
}

View File

@ -0,0 +1,50 @@
/*
* 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.tool.schema.extract.internal;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* @author Vlad Mihalcea
*/
public class SequenceInformationExtractorDB2DatabaseImpl extends SequenceInformationExtractorLegacyImpl {
/**
* Singleton access
*/
public static final SequenceInformationExtractorDB2DatabaseImpl INSTANCE = new SequenceInformationExtractorDB2DatabaseImpl();
@Override
protected String sequenceNameColumn() {
return "seqname";
}
@Override
protected String sequenceCatalogColumn() {
return null;
}
@Override
protected String sequenceSchemaColumn() {
return "seqschema";
}
@Override
protected String sequenceStartValueColumn() {
return "start";
}
@Override
protected String sequenceMinValueColumn() {
return "minvalue";
}
@Override
protected String sequenceMaxValueColumn() {
return "maxvalue";
}
}

View File

@ -0,0 +1,42 @@
/*
* 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.tool.schema.extract.internal;
/**
* @author Vlad Mihalcea
*/
public class SequenceInformationExtractorDerbyDatabaseImpl extends SequenceInformationExtractorLegacyImpl {
/**
* Singleton access
*/
public static final SequenceInformationExtractorDerbyDatabaseImpl INSTANCE = new SequenceInformationExtractorDerbyDatabaseImpl();
@Override
protected String sequenceNameColumn() {
return "sequencename";
}
@Override
protected String sequenceCatalogColumn() {
return null;
}
@Override
protected String sequenceStartValueColumn() {
return "startvalue";
}
@Override
protected String sequenceMinValueColumn() {
return "minimumvalue";
}
@Override
protected String sequenceMaxValueColumn() {
return "maximumvalue";
}
}

View File

@ -8,72 +8,28 @@ package org.hibernate.tool.schema.extract.internal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.boot.model.relational.QualifiedSequenceName;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
import org.hibernate.tool.schema.extract.spi.ExtractionContext;
import org.hibernate.tool.schema.extract.spi.SequenceInformation;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
/**
* Temporary implementation that works for H2.
*
* @author Steve Ebersole
*/
public class SequenceInformationExtractorH2DatabaseImpl implements SequenceInformationExtractor {
public class SequenceInformationExtractorH2DatabaseImpl extends SequenceInformationExtractorLegacyImpl {
/**
* Singleton access
*/
public static final SequenceInformationExtractorH2DatabaseImpl INSTANCE = new SequenceInformationExtractorH2DatabaseImpl();
@Override
public Iterable<SequenceInformation> extractMetadata(ExtractionContext extractionContext) throws SQLException {
final IdentifierHelper identifierHelper = extractionContext.getJdbcEnvironment().getIdentifierHelper();
final Statement statement = extractionContext.getJdbcConnection().createStatement();
try {
ResultSet resultSet = statement.executeQuery(
"select SEQUENCE_CATALOG, SEQUENCE_SCHEMA, SEQUENCE_NAME, INCREMENT " +
"from information_schema.sequences"
);
try {
final List<SequenceInformation> sequenceInformationList = new ArrayList<SequenceInformation>();
while ( resultSet.next() ) {
sequenceInformationList.add(
new SequenceInformationImpl(
new QualifiedSequenceName(
identifierHelper.toIdentifier(
resultSet.getString( "SEQUENCE_CATALOG" )
),
identifierHelper.toIdentifier(
resultSet.getString( "SEQUENCE_SCHEMA" )
),
identifierHelper.toIdentifier(
resultSet.getString( "SEQUENCE_NAME" )
)
),
resultSet.getInt( "INCREMENT" )
)
);
}
return sequenceInformationList;
}
finally {
try {
resultSet.close();
}
catch (SQLException ignore) {
}
}
}
finally {
try {
statement.close();
}
catch (SQLException ignore) {
}
}
protected String sequenceStartValueColumn() {
return null;
}
@Override
protected String sequenceMinValueColumn() {
return "min_value";
}
@Override
protected String sequenceMaxValueColumn() {
return "max_value";
}
}

View File

@ -0,0 +1,50 @@
/*
* 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.tool.schema.extract.internal;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* @author Vlad Mihalcea
*/
public class SequenceInformationExtractorHANADatabaseImpl extends SequenceInformationExtractorLegacyImpl {
/**
* Singleton access
*/
public static final SequenceInformationExtractorHANADatabaseImpl INSTANCE = new SequenceInformationExtractorHANADatabaseImpl();
@Override
protected String sequenceCatalogColumn() {
return null;
}
@Override
protected String sequenceSchemaColumn() {
return "schema_name";
}
@Override
protected String sequenceStartValueColumn() {
return "start_number";
}
@Override
protected String sequenceMinValueColumn() {
return "min_value";
}
@Override
protected String sequenceMaxValueColumn() {
return "max_value";
}
@Override
protected String sequenceIncrementColumn() {
return "increment_by";
}
}

View File

@ -0,0 +1,23 @@
/*
* 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.tool.schema.extract.internal;
/**
* @author Vlad Mihalcea
*/
public class SequenceInformationExtractorHSQLDBDatabaseImpl extends SequenceInformationExtractorLegacyImpl {
/**
* Singleton access
*/
public static final SequenceInformationExtractorHSQLDBDatabaseImpl INSTANCE = new SequenceInformationExtractorHSQLDBDatabaseImpl();
@Override
protected String sequenceStartValueColumn() {
return "start_with";
}
}

View File

@ -0,0 +1,50 @@
/*
* 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.tool.schema.extract.internal;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* @author Vlad Mihalcea
*/
public class SequenceInformationExtractorInformixDatabaseImpl extends SequenceInformationExtractorLegacyImpl {
/**
* Singleton access
*/
public static final SequenceInformationExtractorInformixDatabaseImpl INSTANCE = new SequenceInformationExtractorInformixDatabaseImpl();
@Override
protected String sequenceCatalogColumn() {
return null;
}
@Override
protected String sequenceSchemaColumn() {
return null;
}
@Override
protected String sequenceStartValueColumn() {
return "start_val";
}
@Override
protected String sequenceMinValueColumn() {
return "min_val";
}
@Override
protected String sequenceMaxValueColumn() {
return "max_val";
}
@Override
protected String sequenceIncrementColumn() {
return "inc_val";
}
}

View File

@ -0,0 +1,52 @@
/*
* 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.tool.schema.extract.internal;
/**
* @author Vlad Mihalcea
*/
public class SequenceInformationExtractorIngresDatabaseImpl extends SequenceInformationExtractorLegacyImpl {
/**
* Singleton access
*/
public static final SequenceInformationExtractorIngresDatabaseImpl INSTANCE = new SequenceInformationExtractorIngresDatabaseImpl();
@Override
protected String sequenceNameColumn() {
return "seq_name";
}
@Override
protected String sequenceCatalogColumn() {
return null;
}
@Override
protected String sequenceSchemaColumn() {
return null;
}
@Override
protected String sequenceStartValueColumn() {
return null;
}
@Override
protected String sequenceMinValueColumn() {
return null;
}
@Override
protected String sequenceMaxValueColumn() {
return null;
}
@Override
protected String sequenceIncrementColumn() {
return null;
}
}

View File

@ -41,18 +41,25 @@ public class SequenceInformationExtractorLegacyImpl implements SequenceInformati
try {
final ResultSet resultSet = statement.executeQuery( lookupSql );
try {
final List<SequenceInformation> sequenceInformationList = new ArrayList<SequenceInformation>();
final List<SequenceInformation> sequenceInformationList = new ArrayList<>();
while ( resultSet.next() ) {
sequenceInformationList.add(
new SequenceInformationImpl(
new QualifiedSequenceName(
null,
null,
identifierHelper.toIdentifier(
resultSet.getString( 1 )
resultSetCatalogName( resultSet )
),
identifierHelper.toIdentifier(
resultSetSchemaName( resultSet )
),
identifierHelper.toIdentifier(
resultSetSequenceName( resultSet )
)
),
-1
resultSetStartValueSize( resultSet ),
resultSetMinValue( resultSet ),
resultSetMaxValue( resultSet ),
resultSetIncrementValue( resultSet )
)
);
}
@ -74,4 +81,66 @@ public class SequenceInformationExtractorLegacyImpl implements SequenceInformati
}
}
}
protected String sequenceNameColumn() {
return "sequence_name";
}
protected String sequenceCatalogColumn() {
return "sequence_catalog";
}
protected String sequenceSchemaColumn() {
return "sequence_schema";
}
protected String sequenceStartValueColumn() {
return "start_value";
}
protected String sequenceMinValueColumn() {
return "minimum_value";
}
protected String sequenceMaxValueColumn() {
return "maximum_value";
}
protected String sequenceIncrementColumn() {
return "increment";
}
protected String resultSetSequenceName(ResultSet resultSet) throws SQLException {
return resultSet.getString( sequenceNameColumn() );
}
protected String resultSetCatalogName(ResultSet resultSet) throws SQLException {
String column = sequenceCatalogColumn();
return column != null ? resultSet.getString( column ) : null;
}
protected String resultSetSchemaName(ResultSet resultSet) throws SQLException {
String column = sequenceSchemaColumn();
return column != null ? resultSet.getString( column ) : null;
}
protected Long resultSetStartValueSize(ResultSet resultSet) throws SQLException {
String column = sequenceStartValueColumn();
return column != null ? resultSet.getLong( column ) : null;
}
protected Long resultSetMinValue(ResultSet resultSet) throws SQLException {
String column = sequenceMinValueColumn();
return column != null ? resultSet.getLong( column ) : null;
}
protected Long resultSetMaxValue(ResultSet resultSet) throws SQLException {
String column = sequenceMaxValueColumn();
return column != null ? resultSet.getLong( column ) : null;
}
protected Long resultSetIncrementValue(ResultSet resultSet) throws SQLException {
String column = sequenceIncrementColumn();
return column != null ? resultSet.getLong( column ) : null;
}
}

View File

@ -0,0 +1,27 @@
/*
* 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.tool.schema.extract.internal;
/**
* @author Vlad Mihalcea
*/
public class SequenceInformationExtractorMimerSQLDatabaseImpl extends SequenceInformationExtractorLegacyImpl {
/**
* Singleton access
*/
public static final SequenceInformationExtractorMimerSQLDatabaseImpl INSTANCE = new SequenceInformationExtractorMimerSQLDatabaseImpl();
@Override
protected String sequenceStartValueColumn() {
return "initial_value";
}
@Override
protected String sequenceMinValueColumn() {
return null;
}
}

View File

@ -0,0 +1,50 @@
/*
* 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.tool.schema.extract.internal;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* @author Vlad Mihalcea
*/
public class SequenceInformationExtractorOracleDatabaseImpl extends SequenceInformationExtractorLegacyImpl {
/**
* Singleton access
*/
public static final SequenceInformationExtractorOracleDatabaseImpl INSTANCE = new SequenceInformationExtractorOracleDatabaseImpl();
@Override
protected String sequenceCatalogColumn() {
return null;
}
@Override
protected String sequenceSchemaColumn() {
return null;
}
@Override
protected String sequenceStartValueColumn() {
return null;
}
@Override
protected String sequenceMinValueColumn() {
return "min_value";
}
@Override
protected Long resultSetMaxValue(ResultSet resultSet) throws SQLException {
return resultSet.getBigDecimal( "max_value" ).longValue();
}
@Override
protected String sequenceIncrementColumn() {
return "increment_by";
}
}

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.tool.schema.extract.internal;
/**
* @author Vlad Mihalcea
*/
public class SequenceInformationExtractorSAPDBDatabaseImpl extends SequenceInformationExtractorLegacyImpl {
/**
* Singleton access
*/
public static final SequenceInformationExtractorSAPDBDatabaseImpl INSTANCE = new SequenceInformationExtractorSAPDBDatabaseImpl();
@Override
protected String sequenceCatalogColumn() {
return null;
}
@Override
protected String sequenceSchemaColumn() {
return "schemaname";
}
@Override
protected String sequenceStartValueColumn() {
return null;
}
@Override
protected String sequenceMinValueColumn() {
return "min_value";
}
@Override
protected String sequenceMaxValueColumn() {
return "max_value";
}
@Override
protected String sequenceIncrementColumn() {
return "increment_by";
}
}

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.tool.schema.extract.internal;
/**
* @author Vlad Mihalcea
*/
public class SequenceInformationExtractorTimesTenDatabaseImpl extends SequenceInformationExtractorLegacyImpl {
/**
* Singleton access
*/
public static final SequenceInformationExtractorTimesTenDatabaseImpl INSTANCE = new SequenceInformationExtractorTimesTenDatabaseImpl();
@Override
protected String sequenceNameColumn() {
return "name";
}
@Override
protected String sequenceCatalogColumn() {
return null;
}
@Override
protected String sequenceSchemaColumn() {
return null;
}
@Override
protected String sequenceStartValueColumn() {
return null;
}
@Override
protected String sequenceMinValueColumn() {
return "minval";
}
@Override
protected String sequenceMaxValueColumn() {
return "maxval";
}
}

View File

@ -16,11 +16,22 @@ import org.hibernate.tool.schema.extract.spi.SequenceInformation;
*/
public class SequenceInformationImpl implements SequenceInformation {
private final QualifiedSequenceName sequenceName;
private final int incrementSize;
public SequenceInformationImpl(QualifiedSequenceName sequenceName, int incrementSize) {
private final Long startValue;
private final Long minValue;
private final Long maxValue;
private final Long incrementValue;
public SequenceInformationImpl(
QualifiedSequenceName sequenceName,
Long startValue,
Long minValue,
Long maxValue, Long incrementValue) {
this.sequenceName = sequenceName;
this.incrementSize = incrementSize;
this.startValue = startValue;
this.minValue = minValue;
this.maxValue = maxValue;
this.incrementValue = incrementValue;
}
@Override
@ -29,7 +40,21 @@ public class SequenceInformationImpl implements SequenceInformation {
}
@Override
public int getIncrementSize() {
return incrementSize;
public Long getStartValue() {
return startValue;
}
@Override
public Long getMinValue() {
return minValue;
}
public Long getMaxValue() {
return maxValue;
}
@Override
public Long getIncrementValue() {
return incrementValue;
}
}

View File

@ -0,0 +1,54 @@
/*
* 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.tool.schema.extract.internal;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* @author Vlad Mihalcea
*/
public class SequenceNameExtractorImpl extends SequenceInformationExtractorLegacyImpl {
/**
* Singleton access
*/
public static final SequenceNameExtractorImpl INSTANCE = new SequenceNameExtractorImpl();
protected String resultSetSequenceName(ResultSet resultSet) throws SQLException {
return resultSet.getString( 1 );
}
@Override
protected String sequenceCatalogColumn() {
return null;
}
@Override
protected String sequenceSchemaColumn() {
return null;
}
@Override
protected String sequenceStartValueColumn() {
return null;
}
@Override
protected String sequenceMinValueColumn() {
return null;
}
@Override
protected String sequenceMaxValueColumn() {
return null;
}
@Override
protected String sequenceIncrementColumn() {
return null;
}
}

View File

@ -45,4 +45,46 @@ public interface ExtractionContext {
DatabaseObjectAccess getDatabaseObjectAccess();
void cleanup();
abstract class EmptyExtractionContext implements ExtractionContext {
@Override
public ServiceRegistry getServiceRegistry() {
return null;
}
@Override
public JdbcEnvironment getJdbcEnvironment() {
return null;
}
@Override
public Connection getJdbcConnection() {
return null;
}
@Override
public DatabaseMetaData getJdbcDatabaseMetaData() {
return null;
}
@Override
public Identifier getDefaultCatalog() {
return null;
}
@Override
public Identifier getDefaultSchema() {
return null;
}
@Override
public DatabaseObjectAccess getDatabaseObjectAccess() {
return null;
}
@Override
public void cleanup() {
}
}
}

View File

@ -14,17 +14,52 @@ import org.hibernate.boot.model.relational.QualifiedSequenceName;
* @author Steve Ebersole
*/
public interface SequenceInformation {
/**
* The qualified sequence name.
*
* @return The sequence name
*/
public QualifiedSequenceName getSequenceName();
QualifiedSequenceName getSequenceName();
/**
* Retrieve the extracted increment-size defined for the sequence.
*
* @return The extracted increment size; use a negative number to indicate the increment could not be extracted.
*
* @deprecated use {@link #getIncrementValue()} instead.
*/
public int getIncrementSize();
@Deprecated
default int getIncrementSize() {
Long incrementSize = getIncrementValue();
return incrementSize != null ? incrementSize.intValue() : -1;
}
/**
* Retrieve the extracted start value defined for the sequence.
*
* @return The extracted start value or null id the value could not be extracted.
*/
Long getStartValue();
/**
* Retrieve the extracted minimum value defined for the sequence.
*
* @return The extracted minimum value or null id the value could not be extracted.
*/
Long getMinValue();
/**
* Retrieve the extracted maximum value defined for the sequence.
*
* @return The extracted maximum value or null id the value could not be extracted.
*/
Long getMaxValue();
/**
* Retrieve the extracted increment value defined for the sequence.
*
* @return The extracted increment value; use a negative number to indicate the increment could not be extracted.
*/
Long getIncrementValue();
}

View File

@ -0,0 +1,154 @@
/*
* 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.id.hhh12973;
import java.io.StringReader;
import java.sql.Statement;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration;
import org.hibernate.dialect.PostgreSQL82Dialect;
import org.hibernate.id.SequenceMismatchStrategy;
import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.logger.LoggerInspectionRule;
import org.hibernate.testing.logger.Triggerable;
import org.junit.Rule;
import org.junit.Test;
import org.jboss.logging.Logger;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* @author Vlad Mihalcea
*/
@TestForIssue(jiraKey = "HHH-12973")
@RequiresDialect(PostgreSQL82Dialect.class)
public class PostgreSQLSequenceGeneratorWithSerialTest extends BaseEntityManagerFunctionalTestCase {
@Rule
public LoggerInspectionRule logInspection = new LoggerInspectionRule( Logger.getMessageLogger( CoreMessageLogger.class,
SequenceStyleGenerator.class
.getName()
) );
private Triggerable triggerable = logInspection.watchForLogMessages( "HHH000497:" );
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
ApplicationConfiguration.class,
};
}
private static final String DROP_SEQUENCE = "DROP SEQUENCE IF EXISTS application_configurations_id_seq";
private static final String DROP_TABLE = "DROP TABLE IF EXISTS application_configurations CASCADE";
private static final String CREATE_TABLE = "CREATE TABLE application_configurations (id BIGSERIAL NOT NULL PRIMARY KEY)";
@Override
protected void addMappings(Map settings) {
triggerable.reset();
assertFalse( triggerable.wasTriggered() );
//For this test, we need to make sure the DB is created prior to bootstrapping Hibernate
StandardServiceRegistry ssr = new StandardServiceRegistryBuilder()
.build();
SessionFactory sessionFactory = null;
try {
Configuration config = new Configuration();
sessionFactory = config.buildSessionFactory( ssr );
try(Session session = sessionFactory.openSession()) {
session.doWork( connection -> {
try(Statement statement = connection.createStatement()) {
statement.execute( DROP_TABLE );
statement.execute( DROP_SEQUENCE );
statement.execute( CREATE_TABLE );
}
} );
}
}
finally {
if ( sessionFactory != null ) {
sessionFactory.close();
}
ssr.close();
}
settings.put( AvailableSettings.HBM2DDL_DROP_SCRIPT_SOURCE, new StringReader(
DROP_TABLE + ";" + DROP_SEQUENCE
) );
settings.put( AvailableSettings.SEQUENCE_INCREMENT_SIZE_MISMATCH_STRATEGY, SequenceMismatchStrategy.FIX);
}
@Override
protected void afterEntityManagerFactoryBuilt() {
assertTrue( triggerable.wasTriggered() );
}
@Test
public void test() {
final AtomicLong id = new AtomicLong();
final int ITERATIONS = 51;
doInJPA( this::entityManagerFactory, entityManager -> {
for ( int i = 1; i <= ITERATIONS; i++ ) {
ApplicationConfiguration model = new ApplicationConfiguration();
entityManager.persist( model );
id.set( model.getId() );
}
} );
assertEquals( ITERATIONS, id.get() );
}
@Entity
@Table(name = "application_configurations")
public static class ApplicationConfiguration {
@Id
@javax.persistence.SequenceGenerator(
name = "application_configurations_id_seq",
sequenceName = "application_configurations_id_seq"
)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "application_configurations_id_seq")
private Long id;
public Long getId() {
return id;
}
public void setId(final Long id) {
this.id = id;
}
}
}

View File

@ -0,0 +1,144 @@
/*
* 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.id.hhh12973;
import java.util.EnumSet;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.MappingException;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.schema.TargetType;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.logger.LoggerInspectionRule;
import org.hibernate.testing.logger.Triggerable;
import org.hibernate.testing.util.ExceptionUtil;
import org.junit.Rule;
import org.junit.Test;
import org.jboss.logging.Logger;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assert.assertFalse;
/**
* @author Vlad Mihalcea
*/
@TestForIssue(jiraKey = "HHH-12973")
@RequiresDialectFeature(DialectChecks.SupportsSequences.class)
public class SequenceMismatchStrategyDefaultExceptionTest extends BaseEntityManagerFunctionalTestCase {
protected ServiceRegistry serviceRegistry;
protected MetadataImplementor metadata;
@Override
public void buildEntityManagerFactory() {
serviceRegistry = new StandardServiceRegistryBuilder().build();
metadata = (MetadataImplementor) new MetadataSources( serviceRegistry )
.addAnnotatedClass( ApplicationConfigurationHBM2DDL.class )
.buildMetadata();
new SchemaExport().create( EnumSet.of( TargetType.DATABASE ), metadata );
try {
super.buildEntityManagerFactory();
fail("Should throw MappingException!");
}
catch (Exception e) {
Throwable rootCause = ExceptionUtil.rootCause( e );
assertTrue( rootCause instanceof MappingException );
assertTrue( rootCause.getMessage().contains( "in the entity mapping while the associated database sequence increment size is" ) );
}
}
@Override
public void releaseResources() {
super.releaseResources();
new SchemaExport().drop( EnumSet.of( TargetType.DATABASE ), metadata );
StandardServiceRegistryBuilder.destroy( serviceRegistry );
}
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
ApplicationConfiguration.class,
};
}
@Override
protected void addMappings(Map settings) {
settings.put( AvailableSettings.HBM2DDL_AUTO, "none" );
}
@Test
public void test() {
}
@Entity
@Table(name = "application_configurations")
public static class ApplicationConfigurationHBM2DDL {
@Id
@javax.persistence.SequenceGenerator(
name = "app_config_sequence",
sequenceName = "app_config_sequence",
allocationSize = 1
)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "app_config_sequence")
private Long id;
public Long getId() {
return id;
}
public void setId(final Long id) {
this.id = id;
}
}
@Entity
@Table(name = "application_configurations")
public static class ApplicationConfiguration {
@Id
@javax.persistence.SequenceGenerator(
name = "app_config_sequence",
sequenceName = "app_config_sequence"
)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "app_config_sequence")
private Long id;
public Long getId() {
return id;
}
public void setId(final Long id) {
this.id = id;
}
}
}

View File

@ -0,0 +1,31 @@
/*
* 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.id.hhh12973;
import java.util.Map;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.id.SequenceMismatchStrategy;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
/**
* @author Vlad Mihalcea
*/
@TestForIssue(jiraKey = "HHH-12973")
@RequiresDialectFeature(DialectChecks.SupportsSequences.class)
public class SequenceMismatchStrategyExceptionEnumTest extends SequenceMismatchStrategyDefaultExceptionTest {
@Override
protected void addMappings(Map settings) {
super.addMappings( settings );
settings.put( AvailableSettings.SEQUENCE_INCREMENT_SIZE_MISMATCH_STRATEGY, SequenceMismatchStrategy.EXCEPTION );
}
}

View File

@ -0,0 +1,171 @@
/*
* 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.id.hhh12973;
import java.util.EnumSet;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.dialect.Oracle8iDialect;
import org.hibernate.dialect.PostgreSQL82Dialect;
import org.hibernate.dialect.SQLServer2012Dialect;
import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.schema.TargetType;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.logger.LoggerInspectionRule;
import org.hibernate.testing.logger.Triggerable;
import org.hibernate.test.schemaupdate.SchemaExportWithGlobalQuotingEnabledTest;
import org.junit.Rule;
import org.junit.Test;
import org.jboss.logging.Logger;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* @author Vlad Mihalcea
*/
@TestForIssue(jiraKey = "HHH-12973")
@RequiresDialectFeature(DialectChecks.SupportsSequences.class)
public class SequenceMismatchStrategyFixWithSequenceGeneratorTest extends BaseEntityManagerFunctionalTestCase {
@Rule
public LoggerInspectionRule logInspection = new LoggerInspectionRule(
Logger.getMessageLogger(
CoreMessageLogger.class,
SequenceStyleGenerator.class.getName()
)
);
private Triggerable triggerable = logInspection.watchForLogMessages( "HHH000497:" );
protected ServiceRegistry serviceRegistry;
protected MetadataImplementor metadata;
@Override
public void buildEntityManagerFactory() {
serviceRegistry = new StandardServiceRegistryBuilder().build();
metadata = (MetadataImplementor) new MetadataSources( serviceRegistry )
.addAnnotatedClass( ApplicationConfigurationHBM2DDL.class )
.buildMetadata();
new SchemaExport().create( EnumSet.of( TargetType.DATABASE ), metadata );
super.buildEntityManagerFactory();
}
@Override
public void releaseResources() {
super.releaseResources();
new SchemaExport().drop( EnumSet.of( TargetType.DATABASE ), metadata );
StandardServiceRegistryBuilder.destroy( serviceRegistry );
}
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
ApplicationConfiguration.class,
};
}
@Override
protected void addMappings(Map settings) {
settings.put( AvailableSettings.HBM2DDL_AUTO, "none" );
settings.put( AvailableSettings.SEQUENCE_INCREMENT_SIZE_MISMATCH_STRATEGY, "fix" );
triggerable.reset();
}
@Override
protected void afterEntityManagerFactoryBuilt() {
assertTrue( triggerable.wasTriggered() );
}
@Test
public void test() {
final AtomicLong id = new AtomicLong();
final int ITERATIONS = 51;
doInJPA( this::entityManagerFactory, entityManager -> {
for ( int i = 1; i <= ITERATIONS; i++ ) {
ApplicationConfiguration model = new ApplicationConfiguration();
entityManager.persist( model );
id.set( model.getId() );
}
} );
assertEquals( ITERATIONS, id.get() );
}
@Entity
@Table(name = "application_configurations")
public static class ApplicationConfigurationHBM2DDL {
@Id
@javax.persistence.SequenceGenerator(
name = "app_config_sequence",
sequenceName = "app_config_sequence",
allocationSize = 1
)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "app_config_sequence")
private Long id;
public Long getId() {
return id;
}
public void setId(final Long id) {
this.id = id;
}
}
@Entity
@Table(name = "application_configurations")
public static class ApplicationConfiguration {
@Id
@javax.persistence.SequenceGenerator(
name = "app_config_sequence",
sequenceName = "app_config_sequence"
)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "app_config_sequence")
private Long id;
public Long getId() {
return id;
}
public void setId(final Long id) {
this.id = id;
}
}
}

View File

@ -0,0 +1,146 @@
/*
* 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.id.hhh12973;
import java.util.EnumSet;
import java.util.Map;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.schema.TargetType;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.logger.LoggerInspectionRule;
import org.hibernate.testing.logger.Triggerable;
import org.junit.Rule;
import org.junit.Test;
import org.jboss.logging.Logger;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* @author Vlad Mihalcea
*/
@TestForIssue(jiraKey = "HHH-12973")
@RequiresDialectFeature(DialectChecks.SupportsSequences.class)
public class SequenceMismatchStrategyLogTest extends BaseEntityManagerFunctionalTestCase {
@Rule
public LoggerInspectionRule logInspection = new LoggerInspectionRule(
Logger.getMessageLogger(
CoreMessageLogger.class,
SequenceStyleGenerator.class.getName()
)
);
private Triggerable triggerable = logInspection.watchForLogMessages( "HHH000497:" );
protected ServiceRegistry serviceRegistry;
protected MetadataImplementor metadata;
@Override
public void buildEntityManagerFactory() {
serviceRegistry = new StandardServiceRegistryBuilder().build();
metadata = (MetadataImplementor) new MetadataSources( serviceRegistry )
.addAnnotatedClass( ApplicationConfigurationHBM2DDL.class )
.buildMetadata();
new SchemaExport().create( EnumSet.of( TargetType.DATABASE ), metadata );
super.buildEntityManagerFactory();
}
@Override
public void releaseResources() {
super.releaseResources();
new SchemaExport().drop( EnumSet.of( TargetType.DATABASE ), metadata );
StandardServiceRegistryBuilder.destroy( serviceRegistry );
}
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
ApplicationConfiguration.class,
};
}
@Override
protected void addMappings(Map settings) {
settings.put( AvailableSettings.HBM2DDL_AUTO, "none" );
settings.put( AvailableSettings.SEQUENCE_INCREMENT_SIZE_MISMATCH_STRATEGY, "log" );
triggerable.reset();
assertFalse( triggerable.wasTriggered() );
}
@Override
protected void afterEntityManagerFactoryBuilt() {
assertTrue( triggerable.wasTriggered() );
}
@Test
public void test() {
}
@Entity
@Table(name = "application_configurations")
public static class ApplicationConfigurationHBM2DDL {
@Id
@javax.persistence.SequenceGenerator(
name = "app_config_sequence",
sequenceName = "app_config_sequence",
allocationSize = 1
)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "app_config_sequence")
private Long id;
public Long getId() {
return id;
}
public void setId(final Long id) {
this.id = id;
}
}
@Entity
@Table(name = "application_configurations")
public static class ApplicationConfiguration {
@Id
@javax.persistence.SequenceGenerator(
name = "app_config_sequence",
sequenceName = "app_config_sequence"
)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "app_config_sequence")
private Long id;
public Long getId() {
return id;
}
public void setId(final Long id) {
this.id = id;
}
}
}

View File

@ -0,0 +1,31 @@
/*
* 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.id.hhh12973;
import org.hibernate.id.SequenceMismatchStrategy;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
/**
* @author Vlad Mihalcea
*/
@TestForIssue(jiraKey = "HHH-12973")
public class SequenceMismatchStrategyLowerCaseStringValueTest extends BaseUnitTestCase {
@Test
public void test() {
assertEquals( SequenceMismatchStrategy.EXCEPTION, SequenceMismatchStrategy.interpret( "exception" ) );
assertEquals( SequenceMismatchStrategy.LOG, SequenceMismatchStrategy.interpret( "log" ) );
assertEquals( SequenceMismatchStrategy.FIX, SequenceMismatchStrategy.interpret( "fix" ) );
}
}

View File

@ -0,0 +1,27 @@
/*
* 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.id.hhh12973;
import org.hibernate.id.SequenceMismatchStrategy;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
/**
* @author Vlad Mihalcea
*/
@TestForIssue(jiraKey = "HHH-12973")
public class SequenceMismatchStrategyNullValueTest extends BaseUnitTestCase {
@Test
public void test() {
assertEquals( SequenceMismatchStrategy.EXCEPTION, SequenceMismatchStrategy.interpret( null ) );
}
}

View File

@ -0,0 +1,40 @@
/*
* 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.id.hhh12973;
import org.hibernate.HibernateException;
import org.hibernate.id.SequenceMismatchStrategy;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.hibernate.testing.util.ExceptionUtil;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
* @author Vlad Mihalcea
*/
@TestForIssue(jiraKey = "HHH-12973")
public class SequenceMismatchStrategyUnknownEnumValueTest extends BaseUnitTestCase {
@Test
public void test() {
try {
SequenceMismatchStrategy.interpret( "acme" );
fail("Should throw HibernateException!");
}
catch (Exception e) {
Throwable rootCause = ExceptionUtil.rootCause( e );
assertTrue( rootCause instanceof HibernateException );
assertEquals( "Unrecognized sequence.increment_size_mismatch_strategy value : [acme]. Supported values include [log], [exception], and [fix].", rootCause.getMessage() );
}
}
}

View File

@ -0,0 +1,29 @@
/*
* 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.id.hhh12973;
import org.hibernate.id.SequenceMismatchStrategy;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
/**
* @author Vlad Mihalcea
*/
@TestForIssue(jiraKey = "HHH-12973")
public class SequenceMismatchStrategyUpperCaseStringValueTest extends BaseUnitTestCase {
@Test
public void test() {
assertEquals( SequenceMismatchStrategy.EXCEPTION, SequenceMismatchStrategy.interpret( "EXCEPTION" ) );
assertEquals( SequenceMismatchStrategy.LOG, SequenceMismatchStrategy.interpret( "LOG" ) );
assertEquals( SequenceMismatchStrategy.FIX, SequenceMismatchStrategy.interpret( "FIX" ) );
}
}

View File

@ -0,0 +1,159 @@
/*
* 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.id.hhh12973;
import java.util.EnumSet;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.schema.TargetType;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.logger.LoggerInspectionRule;
import org.hibernate.testing.logger.Triggerable;
import org.junit.Rule;
import org.junit.Test;
import org.jboss.logging.Logger;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* @author Vlad Mihalcea
*/
@TestForIssue(jiraKey = "HHH-12973")
@RequiresDialectFeature(DialectChecks.SupportsSequences.class)
public class SequenceMismatchStrategyWithoutSequenceGeneratorTest extends BaseEntityManagerFunctionalTestCase {
@Rule
public LoggerInspectionRule logInspection = new LoggerInspectionRule(
Logger.getMessageLogger(
CoreMessageLogger.class,
SequenceStyleGenerator.class.getName()
)
);
private Triggerable triggerable = logInspection.watchForLogMessages( "HHH000497:" );
protected ServiceRegistry serviceRegistry;
protected MetadataImplementor metadata;
@Override
public void buildEntityManagerFactory() {
serviceRegistry = new StandardServiceRegistryBuilder().build();
metadata = (MetadataImplementor) new MetadataSources( serviceRegistry )
.addAnnotatedClass( ApplicationConfigurationHBM2DDL.class )
.buildMetadata();
new SchemaExport().create( EnumSet.of( TargetType.DATABASE ), metadata );
super.buildEntityManagerFactory();
}
@Override
public void releaseResources() {
super.releaseResources();
new SchemaExport().drop( EnumSet.of( TargetType.DATABASE ), metadata );
StandardServiceRegistryBuilder.destroy( serviceRegistry );
}
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
ApplicationConfiguration.class,
};
}
@Override
protected void addMappings(Map settings) {
settings.put( AvailableSettings.HBM2DDL_AUTO, "none" );
triggerable.reset();
}
@Override
protected void afterEntityManagerFactoryBuilt() {
assertFalse( triggerable.wasTriggered() );
}
@Test
public void test() {
final AtomicLong id = new AtomicLong();
final int ITERATIONS = 51;
doInJPA( this::entityManagerFactory, entityManager -> {
for ( int i = 1; i <= ITERATIONS; i++ ) {
ApplicationConfiguration model = new ApplicationConfiguration();
entityManager.persist( model );
id.set( model.getId() );
}
} );
assertEquals( ITERATIONS, id.get() );
}
@Entity
@Table(name = "application_configurations")
public static class ApplicationConfigurationHBM2DDL {
@Id
@javax.persistence.SequenceGenerator(
name = "hibernate_sequence",
sequenceName = "hibernate_sequence",
allocationSize = 1
)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "hibernate_sequence")
private Long id;
public Long getId() {
return id;
}
public void setId(final Long id) {
this.id = id;
}
}
@Entity
@Table(name = "application_configurations")
public static class ApplicationConfiguration {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
public Long getId() {
return id;
}
public void setId(final Long id) {
this.id = id;
}
}
}

View File

@ -15,6 +15,7 @@ import javax.persistence.PersistenceException;
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.hibernate.testing.util.ExceptionUtil;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
@ -49,7 +50,7 @@ public class DataSourceInjectionTest {
if(emf != null){
emf.close();
}
Assert.assertTrue( pe.getCause() instanceof FakeDataSourceException );
Assert.assertTrue( ExceptionUtil.rootCause( pe ) instanceof FakeDataSourceException );
}
catch (FakeDataSourceException fde) {
//success

View File

@ -0,0 +1,41 @@
/*
* 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.dialect.functional;
import org.hibernate.dialect.Oracle8iDialect;
import org.hibernate.tool.schema.extract.spi.SequenceInformation;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.TestForIssue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
/**
* @author Vlad Mihalcea
*/
@TestForIssue(jiraKey = "HHH-12973")
@RequiresDialect(value = {
Oracle8iDialect.class
})
public class OracleSequenceInfoTest extends
SequenceInformationTest {
@Override
protected void assertProductSequence(SequenceInformation productSequenceInfo) {
assertNull( productSequenceInfo.getStartValue() );
assertEquals( Long.valueOf( 1 ), productSequenceInfo.getMinValue() );
assertEquals( Long.valueOf( 10 ), productSequenceInfo.getIncrementValue() );
}
@Override
protected void assertVehicleSequenceInfo(SequenceInformation vehicleSequenceInfo) {
assertNull( vehicleSequenceInfo.getStartValue() );
assertEquals( Long.valueOf( 1 ), vehicleSequenceInfo.getMinValue() );
assertEquals( Long.valueOf( 1 ), vehicleSequenceInfo.getIncrementValue() );
}
}

View File

@ -0,0 +1,144 @@
/*
* 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.dialect.functional;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.AbstractHANADialect;
import org.hibernate.dialect.DB2Dialect;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.dialect.HSQLDialect;
import org.hibernate.dialect.InformixDialect;
import org.hibernate.dialect.PostgreSQL81Dialect;
import org.hibernate.dialect.SQLServer2012Dialect;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.schema.TargetType;
import org.hibernate.tool.schema.extract.spi.SequenceInformation;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertFalse;
/**
* @author Vlad Mihalcea
*/
@TestForIssue(jiraKey = "HHH-12973")
@RequiresDialectFeature(DialectChecks.SupportsSequences.class)
public class SequenceInformationTest extends
BaseEntityManagerFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] {
Product.class,
Vehicle.class
};
}
protected ServiceRegistry serviceRegistry;
protected MetadataImplementor metadata;
@Override
public void buildEntityManagerFactory() {
serviceRegistry = new StandardServiceRegistryBuilder().build();
metadata = (MetadataImplementor) new MetadataSources( serviceRegistry )
.addAnnotatedClass( Product.class )
.addAnnotatedClass( Vehicle.class )
.buildMetadata();
new SchemaExport().drop( EnumSet.of( TargetType.DATABASE ), metadata );
new SchemaExport().create( EnumSet.of( TargetType.DATABASE ), metadata );
super.buildEntityManagerFactory();
}
@Override
public void releaseResources() {
super.releaseResources();
new SchemaExport().drop( EnumSet.of( TargetType.DATABASE ), metadata );
StandardServiceRegistryBuilder.destroy( serviceRegistry );
}
@Override
protected void addMappings(Map settings) {
settings.put( AvailableSettings.HBM2DDL_AUTO, "none" );
}
@Test
public void test() {
SequenceInformation productSequenceInfo = sequenceInformation("product_sequence");
assertNotNull( productSequenceInfo );
assertEquals( "product_sequence", productSequenceInfo.getSequenceName().getSequenceName().getText().toLowerCase() );
assertProductSequence( productSequenceInfo );
SequenceInformation vehicleSequenceInfo = sequenceInformation("vehicle_sequence");
assertNotNull( vehicleSequenceInfo );
assertEquals( "vehicle_sequence", vehicleSequenceInfo.getSequenceName().getSequenceName().getText().toLowerCase() );
assertVehicleSequenceInfo( vehicleSequenceInfo );
}
protected void assertProductSequence(SequenceInformation productSequenceInfo) {
assertEquals( Long.valueOf( 10 ), productSequenceInfo.getIncrementValue() );
}
protected void assertVehicleSequenceInfo(SequenceInformation vehicleSequenceInfo) {
assertEquals( Long.valueOf( 1 ), vehicleSequenceInfo.getIncrementValue() );
}
private SequenceInformation sequenceInformation(String sequenceName) {
List<SequenceInformation> sequenceInformationList = entityManagerFactory().unwrap( SessionFactoryImplementor.class ).getJdbcServices().getExtractedMetaDataSupport().getSequenceInformationList();
return sequenceInformationList.stream().filter(
sequenceInformation -> sequenceName.equalsIgnoreCase( sequenceInformation.getSequenceName().getSequenceName().getText() )
).findFirst().orElse( null );
}
@Entity(name = "Product")
public static class Product {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "product_sequence")
@SequenceGenerator( name = "product_sequence", sequenceName = "product_sequence", initialValue = 1, allocationSize = 10)
private Long id;
private String name;
}
@Entity(name = "Vehicle")
public static class Vehicle {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "vehicle_sequence")
@SequenceGenerator( name = "vehicle_sequence", sequenceName = "vehicle_sequence", initialValue = 1, allocationSize = 1)
private Long id;
private String name;
}
}

View File

@ -25,7 +25,7 @@ public class DerbyTenSevenDialectSequenceInformationExtractorTest extends Abstra
@Override
public String expectedQuerySequencesString() {
return "select SEQUENCENAME from SYS.SYSSEQUENCES";
return "select sys.sysschemas.schemaname as sequence_schema, sys.syssequences.* from sys.syssequences left join sys.sysschemas on sys.syssequences.schemaid = sys.sysschemas.schemaid";
}
@Override

View File

@ -25,7 +25,7 @@ public class DerbyTenSixDialectSequenceInformationExtractorTest extends Abstract
@Override
public String expectedQuerySequencesString() {
return "select SEQUENCENAME from SYS.SYSSEQUENCES";
return "select sys.sysschemas.schemaname as sequence_schema, sys.syssequences.* from sys.syssequences left join sys.sysschemas on sys.syssequences.schemaid = sys.sysschemas.schemaid";
}
@Override