Skip to content

Commit

Permalink
HHH-18136 clean up legacy handling of identity columns
Browse files Browse the repository at this point in the history
Signed-off-by: Gavin King <gavin@hibernate.org>
  • Loading branch information
gavinking committed May 17, 2024
1 parent e721180 commit 7d3d17d
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 106 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@

import org.hibernate.Incubating;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.id.PostInsertIdentityPersister;
import org.hibernate.id.insert.GetGeneratedKeysDelegate;
import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;
import org.hibernate.id.insert.InsertReturningDelegate;
import org.hibernate.id.insert.UniqueKeySelectingDelegate;
import org.hibernate.persister.entity.EntityPersister;

import static org.hibernate.generator.EventType.INSERT;
import static org.hibernate.generator.internal.NaturalIdHelper.getNaturalIdPropertyNames;
import static org.hibernate.generator.values.internal.GeneratedValuesHelper.noCustomSql;

Expand Down Expand Up @@ -117,21 +119,18 @@ public interface OnExecutionGenerator extends Generator {
*/
@Incubating
default InsertGeneratedIdentifierDelegate getGeneratedIdentifierDelegate(PostInsertIdentityPersister persister) {
final Dialect dialect = persister.getFactory().getJdbcServices().getDialect();
final SessionFactoryImplementor factory = persister.getFactory();
final Dialect dialect = factory.getJdbcServices().getDialect();
if ( dialect.supportsInsertReturningGeneratedKeys()
&& persister.getFactory().getSessionFactoryOptions().isGetGeneratedKeysEnabled() ) {
return new GetGeneratedKeysDelegate( persister, false, EventType.INSERT );
&& factory.getSessionFactoryOptions().isGetGeneratedKeysEnabled() ) {
return new GetGeneratedKeysDelegate( persister, false, INSERT );
}
else if ( dialect.supportsInsertReturning() && noCustomSql( persister, EventType.INSERT ) ) {
return new InsertReturningDelegate( persister, EventType.INSERT );
else if ( dialect.supportsInsertReturning() && noCustomSql( persister, INSERT ) ) {
return new InsertReturningDelegate( persister, INSERT );
}
else {
// let's just hope the entity has a @NaturalId!
return new UniqueKeySelectingDelegate(
persister,
getUniqueKeyPropertyNames( persister ),
EventType.INSERT
);
return new UniqueKeySelectingDelegate( persister, getUniqueKeyPropertyNames( persister ), INSERT );
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
*/
package org.hibernate.id;

import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.dialect.Dialect;
import org.hibernate.generator.EventType;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.generator.OnExecutionGenerator;
import org.hibernate.id.factory.spi.StandardGenerator;
import org.hibernate.id.insert.BasicSelectingDelegate;
Expand All @@ -16,6 +17,7 @@
import org.hibernate.id.insert.InsertReturningDelegate;
import org.hibernate.id.insert.UniqueKeySelectingDelegate;

import static org.hibernate.generator.EventType.INSERT;
import static org.hibernate.generator.internal.NaturalIdHelper.getNaturalIdPropertyNames;
import static org.hibernate.generator.values.internal.GeneratedValuesHelper.noCustomSql;

Expand Down Expand Up @@ -52,26 +54,23 @@ public String[] getReferencedColumnValues(Dialect dialect) {

@Override
public InsertGeneratedIdentifierDelegate getGeneratedIdentifierDelegate(PostInsertIdentityPersister persister) {
final Dialect dialect = persister.getFactory().getJdbcServices().getDialect();
final SessionFactoryImplementor factory = persister.getFactory();
final Dialect dialect = factory.getJdbcServices().getDialect();
// Try to use generic delegates if the dialects supports them
if ( dialect.supportsInsertReturningGeneratedKeys()
&& persister.getFactory().getSessionFactoryOptions().isGetGeneratedKeysEnabled() ) {
return new GetGeneratedKeysDelegate( persister, false, EventType.INSERT );
final SessionFactoryOptions sessionFactoryOptions = factory.getSessionFactoryOptions();
if ( dialect.supportsInsertReturningGeneratedKeys() && sessionFactoryOptions.isGetGeneratedKeysEnabled() ) {
return new GetGeneratedKeysDelegate( persister, false, INSERT );
}
else if ( dialect.supportsInsertReturning() && noCustomSql( persister, EventType.INSERT ) ) {
return new InsertReturningDelegate( persister, EventType.INSERT );
else if ( dialect.supportsInsertReturning() && noCustomSql( persister, INSERT ) ) {
return new InsertReturningDelegate( persister, INSERT );
}
// Fall back to delegates which only handle identifiers
else if ( persister.getFactory().getSessionFactoryOptions().isGetGeneratedKeysEnabled() ) {
else if ( sessionFactoryOptions.isGetGeneratedKeysEnabled() ) {
return dialect.getIdentityColumnSupport().buildGetGeneratedKeysDelegate( persister, dialect );
}
else if ( persister.getNaturalIdentifierProperties() != null
&& !persister.getEntityMetamodel().isNaturalIdentifierInsertGenerated() ) {
return new UniqueKeySelectingDelegate(
persister,
getNaturalIdPropertyNames( persister ),
EventType.INSERT
);
return new UniqueKeySelectingDelegate( persister, getNaturalIdPropertyNames( persister ), INSERT );
}
else {
return new BasicSelectingDelegate( persister );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,29 +69,7 @@ Generator createIdentifierGenerator(
* @return The appropriate generator instance.
*
* @deprecated use {@link #createIdentifierGenerator(GenerationType, String, String, JavaType, Properties, GeneratorDefinitionResolver)}
* instead
*/
@Deprecated(since = "6.0")
Generator createIdentifierGenerator(String strategy, Type type, Properties parameters);

/**
* Retrieve the class that will be used as the {@link IdentifierGenerator} for the given strategy.
*
* @param strategy The strategy
* @return The generator class.
*
* @deprecated with no replacement. See
* {@link #createIdentifierGenerator(GenerationType, String, String, JavaType, Properties, GeneratorDefinitionResolver)}
*/
@Deprecated(since = "6.0")
Class<? extends Generator> getIdentifierGeneratorClass(String strategy);

/**
* Get the dialect.
* @deprecated should be removed
*
* @return the dialect
*/
@Deprecated(since = "6.2", forRemoval = true)
Dialect getDialect();
}
Original file line number Diff line number Diff line change
Expand Up @@ -198,15 +198,14 @@ public IdentifierGenerator createIdentifierGenerator(
throw new UnsupportedOperationException( "No GenerationTypeStrategy specified" );
}

@Override @Deprecated
public Dialect getDialect() {
private Dialect getDialect() {
if ( dialect == null ) {
dialect = serviceRegistry.requireService( JdbcEnvironment.class ).getDialect();
}
return dialect;
}

@Override
@Override @Deprecated
public Generator createIdentifierGenerator(String strategy, Type type, Properties parameters) {
try {
final Class<? extends Generator> clazz = getIdentifierGeneratorClass( strategy );
Expand Down Expand Up @@ -243,8 +242,7 @@ public boolean useJpaCompliantCreation() {
return true;
}

@Override
public Class<? extends Generator> getIdentifierGeneratorClass(String strategy) {
private Class<? extends Generator> getIdentifierGeneratorClass(String strategy) {
switch ( strategy ) {
case "hilo":
throw new UnsupportedOperationException( "Support for 'hilo' generator has been removed" );
Expand All @@ -257,7 +255,7 @@ public Class<? extends Generator> getIdentifierGeneratorClass(String strategy) {
}
}

protected Class<? extends Generator> generatorClassForName(String strategy) {
private Class<? extends Generator> generatorClassForName(String strategy) {
try {
Class<? extends Generator> clazz =
serviceRegistry.requireService( ClassLoaderService.class )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn
private boolean quoted;
private boolean explicit;
int uniqueInteger;
private boolean identity;
private String comment;
private String defaultValue;
private String generatedAs;
Expand Down Expand Up @@ -143,6 +144,14 @@ public void setExplicit(boolean explicit) {
this.explicit = explicit;
}

public boolean isIdentity() {
return identity;
}

public void setIdentity(boolean identity) {
this.identity = identity;
}

private static boolean isQuoted(String name) {
//TODO: deprecated, remove eventually
return name != null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -680,10 +680,8 @@ else if ( rootClass.getIdentifierProperty() != null ) {

final CompositeNestedGeneratedValueGenerator.GenerationContextLocator locator =
new StandardGenerationContextLocator( rootClass.getEntityName() );
final CompositeNestedGeneratedValueGenerator generator = new CompositeNestedGeneratedValueGenerator(
locator,
getType()
);
final CompositeNestedGeneratedValueGenerator generator =
new CompositeNestedGeneratedValueGenerator( locator, getType() );

final List<Property> properties = getProperties();
for ( int i = 0; i < properties.size(); i++ ) {
Expand Down
13 changes: 4 additions & 9 deletions hibernate-core/src/main/java/org/hibernate/mapping/KeyValue.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,12 @@ Generator createGenerator(

/**
* @deprecated Use {@link #createGenerator(IdentifierGeneratorFactory, Dialect, RootClass)} instead.
* No longer used except in legacy tests.
*
* @return {@code null} if the {@code Generator} returned by {@link #createGenerator} is not an instance
* of {@link IdentifierGenerator}.
*/
@Deprecated(since="6.2")
@Deprecated(since="6.2", forRemoval = true)
default IdentifierGenerator createIdentifierGenerator(
IdentifierGeneratorFactory identifierGeneratorFactory,
Dialect dialect,
Expand All @@ -53,23 +54,17 @@ default IdentifierGenerator createIdentifierGenerator(

/**
* @deprecated Use {@link #createGenerator(IdentifierGeneratorFactory, Dialect, RootClass)} instead.
* No longer used except in legacy tests.
*
* @return {@code null} if the {@code Generator} returned by {@link #createGenerator} is not an instance
* of {@link IdentifierGenerator}.
*/
@Deprecated(since="6.2")
@Deprecated(since="6.2", forRemoval = true)
default IdentifierGenerator createIdentifierGenerator(
IdentifierGeneratorFactory identifierGeneratorFactory,
Dialect dialect,
RootClass rootClass) {
final Generator generator = createGenerator( identifierGeneratorFactory, dialect, rootClass );
return generator instanceof IdentifierGenerator ? (IdentifierGenerator) generator : null;
}

/**
* @deprecated We need to add {@code Column.isIdentity()}
*/
@Deprecated(since="6.2")
boolean isIdentityColumn(IdentifierGeneratorFactory identifierGeneratorFactory, Dialect dialect);

}
37 changes: 16 additions & 21 deletions hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.Mapping;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.IdentityGenerator;
import org.hibernate.id.factory.IdentifierGeneratorFactory;
import org.hibernate.id.factory.spi.CustomIdGeneratorCreationContext;
Expand Down Expand Up @@ -378,18 +377,6 @@ public void createUniqueKey(MetadataBuildingContext context) {
getTable().createUniqueKey( getConstraintColumns(), context );
}

/**
* Returns the cached {@link IdentifierGenerator}, or null if
* {@link #createIdentifierGenerator(IdentifierGeneratorFactory, Dialect, String, String, RootClass)}
* was never completed.
*
* @deprecated not used and no longer supported.
*/
@Deprecated(since = "6.0")
public IdentifierGenerator getIdentifierGenerator() {
return (IdentifierGenerator) generator;
}

@Internal
public void setCustomIdGeneratorCreator(IdentifierGeneratorCreator customIdGeneratorCreator) {
this.customIdGeneratorCreator = customIdGeneratorCreator;
Expand All @@ -415,12 +402,28 @@ public Generator createGenerator(
}
else {
generator = createLegacyIdentifierGenerator(this, identifierGeneratorFactory, dialect, null, null, rootClass );
if ( generator instanceof IdentityGenerator ) {
setColumnToIdentity();
}
}
}

return generator;
}

private void setColumnToIdentity() {
if ( getColumnSpan() != 1 ) {
throw new MappingException( "Identity generation requires exactly one column" );
}
final Selectable column = getColumn(0);
if ( column instanceof Column ) {
( (Column) column).setIdentity( true );
}
else {
throw new MappingException( "Identity generation requires a column" );
}
}

public boolean isUpdateable() {
//needed to satisfy KeyValue
return true;
Expand Down Expand Up @@ -450,14 +453,6 @@ public void setIdentifierGeneratorStrategy(String identifierGeneratorStrategy) {
this.identifierGeneratorStrategy = identifierGeneratorStrategy;
}

@Deprecated
@Override
public boolean isIdentityColumn(IdentifierGeneratorFactory identifierGeneratorFactory, Dialect dialect) {
return IdentityGenerator.class.isAssignableFrom(
identifierGeneratorFactory.getIdentifierGeneratorClass( identifierGeneratorStrategy )
);
}

public Map<String, Object> getIdentifierGeneratorParameters() {
return identifierGeneratorParameters;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

import org.hibernate.boot.Metadata;
import org.hibernate.boot.model.relational.SqlStringGenerationContext;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.mapping.CheckConstraint;
Expand Down Expand Up @@ -173,7 +172,7 @@ private static void appendColumnDefinition(
Table table,
Metadata metadata,
Dialect dialect) {
if ( isIdentityColumn( column, table, metadata, dialect) ) {
if ( isIdentityColumn( column, table, dialect) ) {
// to support dialects that have their own identity data type
if ( dialect.getIdentityColumnSupport().hasDataTypeInIdentityColumn() ) {
definition.append( ' ' ).append( column.getSqlType( metadata ) );
Expand Down Expand Up @@ -213,9 +212,9 @@ private static void appendColumnDefinition(
}
}

private static boolean isIdentityColumn(Column column, Table table, Metadata metadata, Dialect dialect) {
private static boolean isIdentityColumn(Column column, Table table, Dialect dialect) {
// Try to find out the name of the primary key in case the dialect needs it to create an identity
return isPrimaryKeyIdentity( table, metadata, dialect )
return isPrimaryKeyIdentity( table )
&& column.getQuotedName( dialect ).equals( getPrimaryKeyColumnName( table, dialect ) );
}

Expand All @@ -225,20 +224,11 @@ private static String getPrimaryKeyColumnName(Table table, Dialect dialect) {
: null;
}

private static boolean isPrimaryKeyIdentity(Table table, Metadata metadata, Dialect dialect) {
// TODO: this is the much better form moving forward as we move to metamodel
//return hasPrimaryKey
// && table.getPrimaryKey().getColumnSpan() == 1
// && table.getPrimaryKey().getColumn( 0 ).isIdentity();
MetadataImplementor metadataImplementor = (MetadataImplementor) metadata;
private static boolean isPrimaryKeyIdentity(Table table) {
return table.hasPrimaryKey()
&& table.getIdentifierValue() != null
&& table.getIdentifierValue()
.isIdentityColumn(
metadataImplementor.getMetadataBuildingOptions()
.getIdentifierGeneratorFactory(),
dialect
);
&& table.getPrimaryKey().getColumnSpan() == 1
&& table.getPrimaryKey().getColumn( 0 ).isIdentity();

}

private static String normalize(String typeName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public void testIdentifierGeneratorExtendsIdentityGenerator(DomainModelScope sco
final PersistentClass entityBinding = domainModel.getEntityBinding( EntityBean.class.getName() );
final KeyValue identifier = entityBinding.getIdentifier();

assertTrue( identifier.isIdentityColumn( domainModel.getMetadataBuildingOptions().getIdentifierGeneratorFactory(), dialect ) );
assertTrue( identifier.getColumns().get(0).isIdentity() );
}

@Entity(name = "EntityBean")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import org.hibernate.id.factory.IdentifierGeneratorFactory;
import org.hibernate.id.factory.spi.CustomIdGeneratorCreationContext;
import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;
import org.hibernate.mapping.SimpleValue;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.Type;

Expand All @@ -33,8 +32,9 @@ public class NativeGenerator
public NativeGenerator(NativeId nativeId, Member member, CustomIdGeneratorCreationContext creationContext) {
factory = creationContext.getIdentifierGeneratorFactory();
strategy = creationContext.getDatabase().getDialect().getNativeIdentifierGeneratorStrategy();
SimpleValue value = (SimpleValue) creationContext.getProperty().getValue();
value.setIdentifierGeneratorStrategy(strategy);
if ( "identity".equals(strategy) ) {
creationContext.getProperty().getValue().getColumns().get(0).setIdentity(true);
}
}

@Override
Expand Down

0 comments on commit 7d3d17d

Please sign in to comment.