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.StandardConverters;
import org.hibernate.generator.AnnotationBasedGenerator;
import org.hibernate.generator.Assigned;
import org.hibernate.generator.BeforeExecutionGenerator;
import org.hibernate.generator.Generator;
import org.hibernate.generator.GeneratorCreationContext;
import org.hibernate.generator.OnExecutionGenerator;
import org.hibernate.id.Assigned;
import org.hibernate.id.Configurable;
import org.hibernate.id.ForeignGenerator;
import org.hibernate.id.GUIDGenerator;
@ -96,7 +96,7 @@ public class GeneratorBinder {
new IdentifierGeneratorCreator() {
@Override
public Generator createGenerator(CustomIdGeneratorCreationContext context) {
return new Assigned( context.getRootClass().getEntityName() );
return new Assigned();
}
@Override
public boolean isAssigned() {
@ -115,7 +115,7 @@ public class GeneratorBinder {
}
switch (strategy) {
case "assigned":
return Assigned.class;
return org.hibernate.id.Assigned.class;
case "enhanced-sequence":
case "sequence":
return SequenceStyleGenerator.class;
@ -899,7 +899,7 @@ public class GeneratorBinder {
String generatorStrategy,
BeanContainer beanContainer) {
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 );
}
else {

View File

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

View File

@ -6,36 +6,15 @@
*/
package org.hibernate.id;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
/**
* An {@link IdentifierGenerator} that returns the current identifier assigned
* to an instance.
* An {@link IdentifierGenerator} that returns the current identifier assigned to an instance.
*
* @author Gavin King
*
* @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 {
private final String entityName;
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;
}
@Deprecated(since = "7.0", forRemoval = true)
public class Assigned extends org.hibernate.generator.Assigned {
}

View File

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

View File

@ -142,8 +142,8 @@ public class InsertCoordinatorStandard extends AbstractMutationCoordinator imple
for ( int i = 0; i < generators.length; i++ ) {
final Generator generator = generators[i];
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 );
persister.setPropertyValue( entity, i, values[i] );
foundStateDependentGenerator = foundStateDependentGenerator || generator.generatedOnExecution();

View File

@ -561,8 +561,8 @@ public class UpdateCoordinatorStandard extends AbstractMutationCoordinator imple
for ( int i = 0; i < generators.length; i++ ) {
final Generator generator = generators[i];
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 );
entityPersister().setPropertyValue( object, i, newValues[i] );
fieldsPreUpdateNeeded[count++] = i;