HHH-18139 introduce org.hibernate.generator.Assigned

rework the Assigned generator, to eliminate instanceof checks

Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
Gavin King 2024-05-28 00:20:15 +02:00 committed by Steve Ebersole
parent 139ec47bc8
commit 3a0d02bde6
8 changed files with 75 additions and 42 deletions

View File

@ -30,11 +30,11 @@ import org.hibernate.dialect.Dialect;
import org.hibernate.engine.config.spi.ConfigurationService; import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.engine.config.spi.StandardConverters; import org.hibernate.engine.config.spi.StandardConverters;
import org.hibernate.generator.AnnotationBasedGenerator; import org.hibernate.generator.AnnotationBasedGenerator;
import org.hibernate.generator.Assigned;
import org.hibernate.generator.BeforeExecutionGenerator; import org.hibernate.generator.BeforeExecutionGenerator;
import org.hibernate.generator.Generator; import org.hibernate.generator.Generator;
import org.hibernate.generator.GeneratorCreationContext; import org.hibernate.generator.GeneratorCreationContext;
import org.hibernate.generator.OnExecutionGenerator; import org.hibernate.generator.OnExecutionGenerator;
import org.hibernate.id.Assigned;
import org.hibernate.id.Configurable; import org.hibernate.id.Configurable;
import org.hibernate.id.ForeignGenerator; import org.hibernate.id.ForeignGenerator;
import org.hibernate.id.GUIDGenerator; import org.hibernate.id.GUIDGenerator;
@ -96,7 +96,7 @@ public class GeneratorBinder {
new IdentifierGeneratorCreator() { new IdentifierGeneratorCreator() {
@Override @Override
public Generator createGenerator(CustomIdGeneratorCreationContext context) { public Generator createGenerator(CustomIdGeneratorCreationContext context) {
return new Assigned( context.getRootClass().getEntityName() ); return new Assigned();
} }
@Override @Override
public boolean isAssigned() { public boolean isAssigned() {
@ -115,7 +115,7 @@ public class GeneratorBinder {
} }
switch (strategy) { switch (strategy) {
case "assigned": case "assigned":
return Assigned.class; return org.hibernate.id.Assigned.class;
case "enhanced-sequence": case "enhanced-sequence":
case "sequence": case "sequence":
return SequenceStyleGenerator.class; return SequenceStyleGenerator.class;
@ -899,7 +899,7 @@ public class GeneratorBinder {
String generatorStrategy, String generatorStrategy,
BeanContainer beanContainer) { BeanContainer beanContainer) {
if ( ASSIGNED_GENERATOR_NAME.equals( generatorStrategy ) if ( ASSIGNED_GENERATOR_NAME.equals( generatorStrategy )
|| Assigned.class.getName().equals( generatorStrategy ) ) { || org.hibernate.id.Assigned.class.getName().equals( generatorStrategy ) ) {
identifierValue.setCustomIdGeneratorCreator( ASSIGNED_IDENTIFIER_GENERATOR_CREATOR ); identifierValue.setCustomIdGeneratorCreator( ASSIGNED_IDENTIFIER_GENERATOR_CREATOR );
} }
else { else {

View File

@ -114,7 +114,7 @@ public abstract class AbstractSaveEventListener<C>
// and is not yet available // and is not yet available
generatedId = null; generatedId = null;
} }
else if ( generator instanceof Assigned ) { else if ( !generator.generatesOnInsert() ) {
// get it from the entity later, since we need // get it from the entity later, since we need
// the @PrePersist callback to happen first // the @PrePersist callback to happen first
generatedId = null; generatedId = null;
@ -204,10 +204,8 @@ public abstract class AbstractSaveEventListener<C>
if ( generator instanceof Assigned || generator instanceof CompositeNestedGeneratedValueGenerator ) { if ( generator instanceof Assigned || generator instanceof CompositeNestedGeneratedValueGenerator ) {
id = persister.getIdentifier( entity, source ); id = persister.getIdentifier( entity, source );
if ( id == null ) { if ( id == null ) {
throw new IdentifierGenerationException( throw new IdentifierGenerationException( "Identifier of entity '" + persister.getEntityName()
"Identifier of entity '" + persister.getEntityName() + "' must be manually assigned before calling 'persist()'" );
+ "' must be manually assigned before calling 'persist()'"
);
} }
} }

View File

@ -0,0 +1,58 @@
/*
* 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.generator;
import org.hibernate.Internal;
import java.util.EnumSet;
/**
* A {@link Generator} that doesn't generate.
* <p>
* Identifier fields with an {@code Assigned} generator
* must be assigned a value by the application program.
* <p>
* This replaces the {@link org.hibernate.id.Assigned}
* identifier generation strategy from older versions
* of Hibernate.
*
* @since 7.0
*
* @author Gavin King
*/
@Internal
public class Assigned implements Generator {
@Override
public boolean generatedOnExecution() {
return false;
}
@Override
public boolean allowAssignedIdentifiers() {
return true;
}
@Override
public EnumSet<EventType> getEventTypes() {
return EventTypeSets.NONE;
}
@Override
public boolean generatesSometimes() {
return false;
}
@Override
public boolean generatesOnInsert() {
return false;
}
@Override
public boolean generatesOnUpdate() {
return false;
}
}

View File

@ -96,7 +96,6 @@ public interface Generator extends Serializable {
*/ */
boolean generatedOnExecution(); boolean generatedOnExecution();
/** /**
* Determines if the property value is generated when a row is written to the database, * Determines if the property value is generated when a row is written to the database,
* or in Java code that executes before the row is written. * or in Java code that executes before the row is written.

View File

@ -6,36 +6,15 @@
*/ */
package org.hibernate.id; package org.hibernate.id;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
/** /**
* An {@link IdentifierGenerator} that returns the current identifier assigned * An {@link IdentifierGenerator} that returns the current identifier assigned to an instance.
* to an instance.
* *
* @author Gavin King * @author Gavin King
* *
* @implNote This also implements the {@code assigned} generation type in {@code hbm.xml} mappings. * @implNote This also implements the {@code assigned} generation type in {@code hbm.xml} mappings.
*
* @deprecated replaced by {@link org.hibernate.generator.Assigned}
*/ */
public class Assigned implements IdentifierGenerator { @Deprecated(since = "7.0", forRemoval = true)
private final String entityName; public class Assigned extends org.hibernate.generator.Assigned {
public Assigned(String entityName) {
this.entityName = entityName;
}
@Override
public boolean allowAssignedIdentifiers() {
return true;
}
public Object generate(SharedSessionContractImplementor session, Object owner) throws HibernateException {
//TODO: cache the persister, this shows up in yourkit
final Object id = session.getEntityPersister( entityName, owner ).getIdentifier( owner, session );
if ( id == null ) {
throw new IdentifierGenerationException( "Identifier for entity '" + entityName
+ "' must be manually assigned before making the entity persistent" );
}
return id;
}
} }

View File

@ -109,7 +109,6 @@ import org.hibernate.generator.values.GeneratedValues;
import org.hibernate.generator.values.internal.GeneratedValuesHelper; import org.hibernate.generator.values.internal.GeneratedValuesHelper;
import org.hibernate.generator.values.GeneratedValuesMutationDelegate; import org.hibernate.generator.values.GeneratedValuesMutationDelegate;
import org.hibernate.graph.spi.RootGraphImplementor; import org.hibernate.graph.spi.RootGraphImplementor;
import org.hibernate.id.Assigned;
import org.hibernate.id.BulkInsertionCapableIdentifierGenerator; import org.hibernate.id.BulkInsertionCapableIdentifierGenerator;
import org.hibernate.id.IdentifierGenerator; import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.OptimizableGenerator; import org.hibernate.id.OptimizableGenerator;
@ -4673,7 +4672,7 @@ public abstract class AbstractEntityPersister
Object currentId, Object currentId,
Object currentVersion, Object currentVersion,
SharedSessionContractImplementor session) { SharedSessionContractImplementor session) {
if ( entityMetamodel.getIdentifierProperty().getGenerator() instanceof Assigned ) { if ( entityMetamodel.getIdentifierProperty().getGenerator().allowAssignedIdentifiers() ) {
return; return;
} }

View File

@ -142,8 +142,8 @@ public class InsertCoordinatorStandard extends AbstractMutationCoordinator imple
for ( int i = 0; i < generators.length; i++ ) { for ( int i = 0; i < generators.length; i++ ) {
final Generator generator = generators[i]; final Generator generator = generators[i];
if ( generator != null if ( generator != null
&& !generator.generatedOnExecution( entity, session ) && generator.generatesOnInsert()
&& generator.generatesOnInsert() ) { && !generator.generatedOnExecution( entity, session ) ) {
values[i] = ( (BeforeExecutionGenerator) generator ).generate( session, entity, values[i], INSERT ); values[i] = ( (BeforeExecutionGenerator) generator ).generate( session, entity, values[i], INSERT );
persister.setPropertyValue( entity, i, values[i] ); persister.setPropertyValue( entity, i, values[i] );
foundStateDependentGenerator = foundStateDependentGenerator || generator.generatedOnExecution(); foundStateDependentGenerator = foundStateDependentGenerator || generator.generatedOnExecution();

View File

@ -561,8 +561,8 @@ public class UpdateCoordinatorStandard extends AbstractMutationCoordinator imple
for ( int i = 0; i < generators.length; i++ ) { for ( int i = 0; i < generators.length; i++ ) {
final Generator generator = generators[i]; final Generator generator = generators[i];
if ( generator != null if ( generator != null
&& !generator.generatedOnExecution( object, session ) && generator.generatesOnUpdate()
&& generator.generatesOnUpdate() ) { && !generator.generatedOnExecution( object, session ) ) {
newValues[i] = ( (BeforeExecutionGenerator) generator ).generate( session, object, newValues[i], UPDATE ); newValues[i] = ( (BeforeExecutionGenerator) generator ).generate( session, object, newValues[i], UPDATE );
entityPersister().setPropertyValue( object, i, newValues[i] ); entityPersister().setPropertyValue( object, i, newValues[i] );
fieldsPreUpdateNeeded[count++] = i; fieldsPreUpdateNeeded[count++] = i;