HHH-18679 Allow `@Generated(writable=true)` with assigned identifiers

This commit is contained in:
Marco Belladelli 2024-10-10 12:06:11 +02:00
parent 7b81b4d5e5
commit 810842ac74
2 changed files with 40 additions and 6 deletions

View File

@ -6,8 +6,11 @@ package org.hibernate.generator.internal;
import org.hibernate.annotations.Generated;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.generator.BeforeExecutionGenerator;
import org.hibernate.generator.EventType;
import org.hibernate.generator.OnExecutionGenerator;
import org.hibernate.persister.entity.EntityPersister;
import java.util.EnumSet;
@ -23,7 +26,7 @@ import static org.hibernate.internal.util.StringHelper.isEmpty;
* @author Steve Ebersole
* @author Gunnar Morling
*/
public class GeneratedGeneration implements OnExecutionGenerator {
public class GeneratedGeneration implements OnExecutionGenerator, BeforeExecutionGenerator {
private final EnumSet<EventType> eventTypes;
private final boolean writable;
@ -60,4 +63,32 @@ public class GeneratedGeneration implements OnExecutionGenerator {
public boolean writePropertyValue() {
return writable && sql==null;
}
@Override
public boolean generatedOnExecution() {
return true;
}
@Override
public boolean generatedOnExecution(Object entity, SharedSessionContractImplementor session) {
if ( !writable ) {
return true;
}
// When this is the identifier generator and writable is true, allow pre-assigned identifiers
final EntityPersister entityPersister = session.getEntityPersister( null, entity );
return entityPersister.getGenerator() != this || entityPersister.getIdentifier( entity, session ) == null;
}
@Override
public Object generate(SharedSessionContractImplementor session, Object owner, Object currentValue, EventType eventType) {
final EntityPersister entityPersister = session.getEntityPersister( null, owner );
assert entityPersister.getGenerator() == this;
return entityPersister.getIdentifier( owner, session );
}
@Override
public boolean allowAssignedIdentifiers() {
return writable;
}
}

View File

@ -24,6 +24,7 @@ import org.hibernate.generator.Generator;
import org.hibernate.generator.OnExecutionGenerator;
import org.hibernate.generator.values.GeneratedValues;
import org.hibernate.generator.values.GeneratedValuesMutationDelegate;
import org.hibernate.id.IdentifierGenerationException;
import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.metamodel.mapping.AttributeMappingsList;
import org.hibernate.metamodel.mapping.BasicEntityIdentifierMapping;
@ -433,11 +434,13 @@ public class InsertCoordinatorStandard extends AbstractMutationCoordinator imple
if ( generator.referenceColumnsInSql( dialect ) ) {
final BasicEntityIdentifierMapping identifierMapping = (BasicEntityIdentifierMapping) entityPersister().getIdentifierMapping();
final String[] columnValues = generator.getReferencedColumnValues( dialect );
tableMapping.getKeyMapping().forEachKeyColumn( (i, column) -> tableInsertBuilder.addKeyColumn(
column.getColumnName(),
columnValues[i],
identifierMapping.getJdbcMapping()
) );
if ( columnValues != null ) {
tableMapping.getKeyMapping().forEachKeyColumn( (i, column) -> tableInsertBuilder.addKeyColumn(
column.getColumnName(),
columnValues[i],
identifierMapping.getJdbcMapping()
) );
}
}
}
else {