Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,11 @@
import org.hibernate.generator.GeneratorCreationContext;
import org.hibernate.id.Configurable;
import org.hibernate.id.OptimizableGenerator;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.id.enhanced.LegacyNamingStrategy;
import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.id.enhanced.SingleNamingStrategy;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.RootClass;
import org.hibernate.mapping.Table;

import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.TableGenerator;
Expand All @@ -40,10 +38,19 @@
import static org.hibernate.id.OptimizableGenerator.IMPLICIT_NAME_BASE;
import static org.hibernate.id.OptimizableGenerator.INCREMENT_PARAM;
import static org.hibernate.id.OptimizableGenerator.INITIAL_PARAM;
import static org.hibernate.id.PersistentIdentifierGenerator.CATALOG;
import static org.hibernate.id.PersistentIdentifierGenerator.OPTIONS;
import static org.hibernate.id.PersistentIdentifierGenerator.PK;
import static org.hibernate.id.PersistentIdentifierGenerator.SCHEMA;
import static org.hibernate.id.PersistentIdentifierGenerator.TABLE;
import static org.hibernate.id.PersistentIdentifierGenerator.TABLES;
import static org.hibernate.boot.BootLogging.BOOT_LOGGER;
import static org.hibernate.id.enhanced.SequenceStyleGenerator.SEQUENCE_PARAM;
import static org.hibernate.id.enhanced.TableGenerator.CONFIG_PREFER_SEGMENT_PER_ENTITY;
import static org.hibernate.id.enhanced.TableGenerator.SEGMENT_COLUMN_PARAM;
import static org.hibernate.id.enhanced.TableGenerator.SEGMENT_VALUE_PARAM;
import static org.hibernate.id.enhanced.TableGenerator.TABLE_PARAM;
import static org.hibernate.id.enhanced.TableGenerator.VALUE_COLUMN_PARAM;
import static org.hibernate.internal.util.StringHelper.isNotBlank;
import static org.hibernate.internal.util.collections.CollectionHelper.isNotEmpty;

Expand Down Expand Up @@ -111,16 +118,14 @@ static void collectBaselineProperties(
BiConsumer<String,String> parameterCollector,
ConfigurationService configService) {
//init the table here instead of earlier, so that we can get a quoted table name
//TODO: would it be better to simply pass the qualified table name, instead of
// splitting it up into schema/catalog/table names
final String tableName = identifierValue.getTable().getQuotedName( dialect );
parameterCollector.accept( TABLE, tableName );
//TODO: would it be better to simply pass the qualified table name,
// instead of splitting it up into schema/catalog/table names
parameterCollector.accept( TABLE, identifierValue.getTable().getQuotedName( dialect ) );

//pass the column name (a generated id almost always has a single column)
if ( identifierValue.getColumnSpan() == 1 ) {
final Column column = (Column) identifierValue.getSelectables().get( 0 );
final String columnName = column.getQuotedName( dialect );
parameterCollector.accept( PK, columnName );
final var column = (Column) identifierValue.getSelectables().get( 0 );
parameterCollector.accept( PK, column.getQuotedName( dialect ) );
}

//pass the entity-name, if not a collection-id
Expand All @@ -139,25 +144,35 @@ static void collectBaselineProperties(
parameterCollector.accept( TABLES, identityTablesString( dialect, rootClass ) );
}
else {
parameterCollector.accept( TABLES, tableName );
parameterCollector.accept( IMPLICIT_NAME_BASE, tableName );
parameterCollector.accept( TABLES, identifierValue.getTable().getQuotedName( dialect ) );
parameterCollector.accept( IMPLICIT_NAME_BASE, identifierValue.getTable().getQuotedName( dialect ) );
}

parameterCollector.accept( CONTRIBUTOR_NAME,
identifierValue.getBuildingContext().getCurrentContributorName() );

final Map<String, Object> settings = configService.getSettings();
final var settings = configService.getSettings();
if ( settings.containsKey( PREFERRED_POOLED_OPTIMIZER ) ) {
parameterCollector.accept(
PREFERRED_POOLED_OPTIMIZER,
(String) settings.get( PREFERRED_POOLED_OPTIMIZER )
);
parameterCollector.accept( PREFERRED_POOLED_OPTIMIZER,
optimizerClassName( settings.get( PREFERRED_POOLED_OPTIMIZER ) ) );
}
}

private static String optimizerClassName(Object optimizerSetting) {
if ( optimizerSetting instanceof String string ) {
return string;
}
else if ( optimizerSetting instanceof Class<?> clazz ) {
return clazz.getName();
}
else {
return optimizerSetting.toString();
}
}

public static String identityTablesString(Dialect dialect, RootClass rootClass) {
final var tables = new StringBuilder();
for ( Table table : rootClass.getIdentityTables() ) {
for ( var table : rootClass.getIdentityTables() ) {
tables.append( table.getQuotedName( dialect ) );
if ( !tables.isEmpty() ) {
tables.append( ", " );
Expand Down Expand Up @@ -188,67 +203,51 @@ public static void interpretTableGenerator(
IdentifierGeneratorDefinition.Builder definitionBuilder) {
definitionBuilder.setName( tableGeneratorAnnotation.name() );
definitionBuilder.setStrategy( org.hibernate.id.enhanced.TableGenerator.class.getName() );
definitionBuilder.addParam( org.hibernate.id.enhanced.TableGenerator.CONFIG_PREFER_SEGMENT_PER_ENTITY, "true" );
definitionBuilder.addParam( CONFIG_PREFER_SEGMENT_PER_ENTITY, "true" );

final String catalog = tableGeneratorAnnotation.catalog();
if ( isNotBlank( catalog ) ) {
definitionBuilder.addParam( PersistentIdentifierGenerator.CATALOG, catalog );
definitionBuilder.addParam( CATALOG, catalog );
}

final String schema = tableGeneratorAnnotation.schema();
if ( isNotBlank( schema ) ) {
definitionBuilder.addParam( PersistentIdentifierGenerator.SCHEMA, schema );
definitionBuilder.addParam( SCHEMA, schema );
}

final String table = tableGeneratorAnnotation.table();
if ( isNotBlank( table ) ) {
definitionBuilder.addParam( org.hibernate.id.enhanced.TableGenerator.TABLE_PARAM, table );
definitionBuilder.addParam( TABLE_PARAM, table );
}

final String pkColumnName = tableGeneratorAnnotation.pkColumnName();
if ( isNotBlank( pkColumnName ) ) {
definitionBuilder.addParam(
org.hibernate.id.enhanced.TableGenerator.SEGMENT_COLUMN_PARAM,
pkColumnName
);
definitionBuilder.addParam( SEGMENT_COLUMN_PARAM, pkColumnName );
}

final String pkColumnValue = tableGeneratorAnnotation.pkColumnValue();
if ( isNotBlank( pkColumnValue ) ) {
definitionBuilder.addParam(
org.hibernate.id.enhanced.TableGenerator.SEGMENT_VALUE_PARAM,
pkColumnValue
);
definitionBuilder.addParam( SEGMENT_VALUE_PARAM, pkColumnValue );
}

final String valueColumnName = tableGeneratorAnnotation.valueColumnName();
if ( isNotBlank( valueColumnName ) ) {
definitionBuilder.addParam(
org.hibernate.id.enhanced.TableGenerator.VALUE_COLUMN_PARAM,
valueColumnName
);
definitionBuilder.addParam( VALUE_COLUMN_PARAM, valueColumnName );
}

final String options = tableGeneratorAnnotation.options();
if ( isNotBlank( options ) ) {
definitionBuilder.addParam(
PersistentIdentifierGenerator.OPTIONS,
options
);
definitionBuilder.addParam( OPTIONS, options );
}

definitionBuilder.addParam(
INCREMENT_PARAM,
String.valueOf( tableGeneratorAnnotation.allocationSize() )
);
definitionBuilder.addParam( INCREMENT_PARAM,
String.valueOf( tableGeneratorAnnotation.allocationSize() ) );

// See comment on HHH-4884 wrt initialValue. Basically initialValue is really the stated value + 1
definitionBuilder.addParam(
INITIAL_PARAM,
String.valueOf( tableGeneratorAnnotation.initialValue() + 1 )
);
// See comment on HHH-4884 wrt initialValue. Basically initialValue is really the stated value + 1
definitionBuilder.addParam( INITIAL_PARAM,
String.valueOf( tableGeneratorAnnotation.initialValue() + 1 ) );

// TODO : implement unique-constraint support
// TODO: implement unique constraint support
if ( isNotEmpty( tableGeneratorAnnotation.uniqueConstraints() ) ) {
BOOT_LOGGER.ignoringTableGeneratorConstraints( tableGeneratorAnnotation.name() );
}
Expand All @@ -263,31 +262,27 @@ public static void interpretSequenceGenerator(

final String catalog = sequenceGeneratorAnnotation.catalog();
if ( isNotBlank( catalog ) ) {
definitionBuilder.addParam( PersistentIdentifierGenerator.CATALOG, catalog );
definitionBuilder.addParam( CATALOG, catalog );
}

final String schema = sequenceGeneratorAnnotation.schema();
if ( isNotBlank( schema ) ) {
definitionBuilder.addParam( PersistentIdentifierGenerator.SCHEMA, schema );
definitionBuilder.addParam( SCHEMA, schema );
}

final String sequenceName = sequenceGeneratorAnnotation.sequenceName();
if ( isNotBlank( sequenceName ) ) {
definitionBuilder.addParam( SequenceStyleGenerator.SEQUENCE_PARAM, sequenceName );
definitionBuilder.addParam( SEQUENCE_PARAM, sequenceName );
}

definitionBuilder.addParam(
INCREMENT_PARAM,
String.valueOf( sequenceGeneratorAnnotation.allocationSize() )
);
definitionBuilder.addParam(
INITIAL_PARAM,
String.valueOf( sequenceGeneratorAnnotation.initialValue() )
);
definitionBuilder.addParam( INCREMENT_PARAM,
String.valueOf( sequenceGeneratorAnnotation.allocationSize() ) );
definitionBuilder.addParam( INITIAL_PARAM,
String.valueOf( sequenceGeneratorAnnotation.initialValue() ) );

final String options = sequenceGeneratorAnnotation.options();
if ( isNotBlank( options ) ) {
definitionBuilder.addParam( PersistentIdentifierGenerator.OPTIONS, options );
definitionBuilder.addParam( OPTIONS, options );
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,20 @@ public interface MappingSettings {
String KEYWORD_AUTO_QUOTING_ENABLED = "hibernate.auto_quote_keyword";

/**
* When a generator specifies an increment size and an optimizer was not explicitly
* specified, which of the "pooled" optimizers should be preferred? Can specify an
* optimizer short name or the name of a class which implements
* {@link org.hibernate.id.enhanced.Optimizer}.
* Specifies an {@linkplain org.hibernate.id.enhanced.Optimizer optimizer}
* which should be used when a generator specifies an {@code allocationSize}
* and no optimizer is not explicitly specified, either:
* <ul>
* <li>a class implementing {@link org.hibernate.id.enhanced.Optimizer},
* <li>the name of a class implementing {@code Optimizer}, or</li>
* <li>an {@linkplain StandardOptimizerDescriptor optimizer short name}.
* </ul>
*
* @settingDefault {@link StandardOptimizerDescriptor#POOLED}
*
* @see org.hibernate.id.enhanced.PooledOptimizer
* @see org.hibernate.id.enhanced.PooledLoOptimizer
* @see org.hibernate.id.enhanced.HiLoOptimizer
*/
String PREFERRED_POOLED_OPTIMIZER = "hibernate.id.optimizer.pooled.preferred";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

import org.hibernate.internal.util.BytesHelper;

import static java.lang.System.currentTimeMillis;

/**
* The base class for identifier generators that use a UUID algorithm. This
* class implements the algorithm, subclasses define the identifier
Expand All @@ -34,7 +36,7 @@ public abstract class AbstractUUIDGenerator implements IdentifierGenerator {
}

private static short counter = (short) 0;
private static final int JVM = (int) ( System.currentTimeMillis() >>> 8 );
private static final int JVM = (int) ( currentTimeMillis() >>> 8 );

public AbstractUUIDGenerator() {
}
Expand Down Expand Up @@ -72,10 +74,10 @@ protected int getIP() {
* Unique down to millisecond
*/
protected short getHiTime() {
return (short) ( System.currentTimeMillis() >>> 32 );
return (short) ( currentTimeMillis() >>> 32 );
}

protected int getLoTime() {
return (int) System.currentTimeMillis();
return (int) currentTimeMillis();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import java.util.ArrayList;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Internal;
import org.hibernate.boot.model.relational.Database;
import org.hibernate.boot.model.relational.ExportableProducer;
Expand Down Expand Up @@ -131,32 +130,9 @@ public void addGeneratedValuePlan(GenerationPlan plan) {
}

@Override
public Object generate(SharedSessionContractImplementor session, Object object) throws HibernateException {
public Object generate(SharedSessionContractImplementor session, Object object) {
final Object context = generationContextLocator.locateGenerationContext( session, object );

final List<Object> generatedValues = compositeType.isMutable() ?
null :
new ArrayList<>( generationPlans.size() );
for ( GenerationPlan generationPlan : generationPlans ) {
final BeforeExecutionGenerator generator = generationPlan.getGenerator();
final Object generated;
if ( generator.generatedBeforeExecution( object, session ) ) {
final Object currentValue = generator.allowAssignedIdentifiers()
? compositeType.getPropertyValue( context, generationPlan.getPropertyIndex(), session )
: null;
generated = generator.generate( session, object, currentValue, INSERT );
}
else {
throw new IdentifierGenerationException( "Identity generation isn't supported for composite ids" );
}
if ( generatedValues != null ) {
generatedValues.add( generated );
}
else {
generationPlan.getInjector().set( context, generated );
}
}

final List<Object> generatedValues = generatedValues( session, object, context );
if ( generatedValues != null) {
final Object[] values = compositeType.getPropertyValues( context );
for ( int i = 0; i < generatedValues.size(); i++ ) {
Expand All @@ -169,16 +145,41 @@ public Object generate(SharedSessionContractImplementor session, Object object)
}
}

private List<Object> generatedValues(SharedSessionContractImplementor session, Object object, Object context) {
final List<Object> generatedValues =
compositeType.isMutable()
? null
: new ArrayList<>( generationPlans.size() );
for ( var generationPlan : generationPlans ) {
final var generator = generationPlan.getGenerator();
if ( !generator.generatedBeforeExecution( object, session ) ) {
throw new IdentifierGenerationException( "Identity generation isn't supported for composite ids" );
}
final Object currentValue =
generator.allowAssignedIdentifiers()
? compositeType.getPropertyValue( context, generationPlan.getPropertyIndex(), session )
: null;
final Object generated = generator.generate( session, object, currentValue, INSERT );
if ( generatedValues != null ) {
generatedValues.add( generated );
}
else {
generationPlan.getInjector().set( context, generated );
}
}
return generatedValues;
}

@Override
public void registerExportables(Database database) {
for ( GenerationPlan plan : generationPlans ) {
for ( var plan : generationPlans ) {
plan.registerExportables( database );
}
}

@Override
public void initialize(SqlStringGenerationContext context) {
for ( GenerationPlan plan : generationPlans ) {
for ( var plan : generationPlans ) {
plan.initialize( context );
}
}
Expand Down
13 changes: 7 additions & 6 deletions hibernate-core/src/main/java/org/hibernate/id/GUIDGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,22 @@ public Object generate(SharedSessionContractImplementor session, Object obj) thr
final String sql = session.getJdbcServices().getJdbcEnvironment().getDialect().getSelectGUIDString();
try {
final var jdbcCoordinator = session.getJdbcCoordinator();
final var st = jdbcCoordinator.getStatementPreparer().prepareStatement( sql );
final var statement = jdbcCoordinator.getStatementPreparer().prepareStatement( sql );
final var resourceRegistry = jdbcCoordinator.getLogicalConnection().getResourceRegistry();
try {
final var rs = jdbcCoordinator.getResultSetReturn().extract( st, sql );
final var resultSet = jdbcCoordinator.getResultSetReturn().extract( statement, sql );
try {
if ( !rs.next() ) {
if ( !resultSet.next() ) {
throw new HibernateException( "The database returned no GUID identity value" );
}
return rs.getString( 1 );
return resultSet.getString( 1 );
}
finally {
jdbcCoordinator.getLogicalConnection().getResourceRegistry().release( rs, st );
resourceRegistry.release( resultSet, statement );
}
}
finally {
jdbcCoordinator.getLogicalConnection().getResourceRegistry().release( st );
resourceRegistry.release( statement );
jdbcCoordinator.afterStatementExecution();
}
}
Expand Down
Loading