HHH-16957 Embeddable cannot have only one @generated field
This commit is contained in:
parent
9e7a2d0f33
commit
74422feead
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
* Copyright Red Hat Inc. and Hibernate Authors
|
||||
*/
|
||||
package org.hibernate.generator;
|
||||
|
||||
public interface CompositeOnExecutionGenerator extends OnExecutionGenerator {
|
||||
OnExecutionGenerator getPropertyGenerator(String propertyName);
|
||||
}
|
|
@ -20,6 +20,8 @@ public abstract class AbstractSingularAttributeMapping
|
|||
extends AbstractStateArrayContributorMapping
|
||||
implements SingularAttributeMapping {
|
||||
|
||||
private Generator generator;
|
||||
|
||||
public AbstractSingularAttributeMapping(
|
||||
String name,
|
||||
int stateArrayPosition,
|
||||
|
@ -52,7 +54,20 @@ public abstract class AbstractSingularAttributeMapping
|
|||
|
||||
@Override
|
||||
public Generator getGenerator() {
|
||||
return findContainingEntityMapping().getEntityPersister().getEntityMetamodel().getGenerators()[getStateArrayPosition()];
|
||||
if ( generator != null ) {
|
||||
return generator;
|
||||
}
|
||||
final int stateArrayPosition = getStateArrayPosition();
|
||||
if ( stateArrayPosition < 0 ) {
|
||||
return null;
|
||||
}
|
||||
final Generator[] generators = findContainingEntityMapping().getEntityPersister().getEntityMetamodel()
|
||||
.getGenerators();
|
||||
if ( generators.length == 0 ) {
|
||||
return null;
|
||||
}
|
||||
generator = generators[stateArrayPosition];
|
||||
return generator;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,6 +24,9 @@ import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
|||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.spi.CascadeStyle;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.generator.CompositeOnExecutionGenerator;
|
||||
import org.hibernate.generator.Generator;
|
||||
import org.hibernate.generator.OnExecutionGenerator;
|
||||
import org.hibernate.mapping.AggregateColumn;
|
||||
import org.hibernate.mapping.Any;
|
||||
import org.hibernate.mapping.BasicValue;
|
||||
|
@ -171,6 +174,7 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
|
|||
private final boolean aggregateMappingRequiresColumnWriter;
|
||||
private final boolean preferSelectAggregateMapping;
|
||||
private final boolean preferBindAggregateMapping;
|
||||
private final CompositeOnExecutionGenerator generator;
|
||||
|
||||
private EmbeddableMappingTypeImpl(
|
||||
Component bootDescriptor,
|
||||
|
@ -251,6 +255,7 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
|
|||
this.preferSelectAggregateMapping = false;
|
||||
this.preferBindAggregateMapping = false;
|
||||
}
|
||||
this.generator = resolveOnExecutionGenerator( valueMapping );
|
||||
}
|
||||
|
||||
private JdbcMapping resolveJdbcMapping(Component bootDescriptor, RuntimeModelCreationContext creationContext) {
|
||||
|
@ -371,6 +376,7 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
|
|||
attributeMappings
|
||||
)
|
||||
);
|
||||
this.generator = resolveOnExecutionGenerator( valueMapping );
|
||||
}
|
||||
|
||||
public EmbeddableMappingType createInverseMappingType(
|
||||
|
@ -436,13 +442,17 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
|
|||
|
||||
// Reset the attribute mappings that were added in previous attempts
|
||||
attributeMappings.clear();
|
||||
|
||||
for ( final Property bootPropertyDescriptor : bootDescriptor.getProperties() ) {
|
||||
|
||||
final AttributeMapping attributeMapping;
|
||||
|
||||
final Type subtype = subtypes[attributeIndex];
|
||||
final Value value = bootPropertyDescriptor.getValue();
|
||||
final String name = bootPropertyDescriptor.getName();
|
||||
if ( subtype instanceof BasicType ) {
|
||||
boolean isInsertable = isInsertable( generator, insertability[columnPosition], name );
|
||||
boolean isUpdatable = isUpdatable( generator, updateability[columnPosition], name );
|
||||
|
||||
final BasicValue basicValue = (BasicValue) value;
|
||||
final Selectable selectable = dependantValue != null ?
|
||||
dependantValue.getColumns().get( dependantColumnIndex + columnPosition ) :
|
||||
|
@ -474,7 +484,7 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
|
|||
containingTableExpression = rootTableExpression;
|
||||
columnExpression = rootTableKeyColumnNames[columnPosition];
|
||||
}
|
||||
final NavigableRole role = valueMapping.getNavigableRole().append( bootPropertyDescriptor.getName() );
|
||||
final NavigableRole role = valueMapping.getNavigableRole().append( name );
|
||||
final SelectablePath selectablePath;
|
||||
final String columnDefinition;
|
||||
final Long length;
|
||||
|
@ -502,10 +512,10 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
|
|||
temporalPrecision = null;
|
||||
isLob = false;
|
||||
nullable = bootPropertyDescriptor.isOptional();
|
||||
selectablePath = new SelectablePath( determineEmbeddablePrefix() + bootPropertyDescriptor.getName() );
|
||||
selectablePath = new SelectablePath( determineEmbeddablePrefix() + name );
|
||||
}
|
||||
attributeMapping = MappingModelCreationHelper.buildBasicAttributeMapping(
|
||||
bootPropertyDescriptor.getName(),
|
||||
name,
|
||||
role,
|
||||
attributeIndex,
|
||||
attributeIndex,
|
||||
|
@ -525,8 +535,8 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
|
|||
temporalPrecision,
|
||||
isLob,
|
||||
nullable,
|
||||
insertability[columnPosition],
|
||||
updateability[columnPosition],
|
||||
isInsertable,
|
||||
isUpdatable,
|
||||
representationStrategy.resolvePropertyAccess( bootPropertyDescriptor ),
|
||||
compositeType.getCascadeStyle( attributeIndex ),
|
||||
creationProcess
|
||||
|
@ -556,7 +566,7 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
|
|||
);
|
||||
|
||||
attributeMapping = new DiscriminatedAssociationAttributeMapping(
|
||||
valueMapping.getNavigableRole().append( bootPropertyDescriptor.getName() ),
|
||||
valueMapping.getNavigableRole().append( name ),
|
||||
typeConfiguration.getJavaTypeRegistry().getDescriptor( Object.class ),
|
||||
this,
|
||||
attributeIndex,
|
||||
|
@ -585,7 +595,7 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
|
|||
}
|
||||
|
||||
attributeMapping = MappingModelCreationHelper.buildEmbeddedAttributeMapping(
|
||||
bootPropertyDescriptor.getName(),
|
||||
name,
|
||||
attributeIndex,
|
||||
attributeIndex,
|
||||
bootPropertyDescriptor,
|
||||
|
@ -604,7 +614,7 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
|
|||
}
|
||||
else if ( subtype instanceof CollectionType ) {
|
||||
attributeMapping = MappingModelCreationHelper.buildPluralAttributeMapping(
|
||||
bootPropertyDescriptor.getName(),
|
||||
name,
|
||||
attributeIndex,
|
||||
attributeIndex,
|
||||
bootPropertyDescriptor,
|
||||
|
@ -619,8 +629,8 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
|
|||
final EntityPersister entityPersister = creationProcess.getEntityPersister( bootDescriptor.getOwner().getEntityName() );
|
||||
|
||||
attributeMapping = MappingModelCreationHelper.buildSingularAssociationAttributeMapping(
|
||||
bootPropertyDescriptor.getName(),
|
||||
valueMapping.getNavigableRole().append( bootPropertyDescriptor.getName() ),
|
||||
name,
|
||||
valueMapping.getNavigableRole().append( name ),
|
||||
attributeIndex,
|
||||
attributeIndex,
|
||||
bootPropertyDescriptor,
|
||||
|
@ -639,7 +649,7 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
|
|||
Locale.ROOT,
|
||||
"Unable to determine attribute nature : %s#%s",
|
||||
bootDescriptor.getOwner().getEntityName(),
|
||||
bootPropertyDescriptor.getName()
|
||||
name
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -667,6 +677,30 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
|
|||
return true;
|
||||
}
|
||||
|
||||
private boolean isInsertable(CompositeOnExecutionGenerator generator, boolean propertyInsertability, String propertyName) {
|
||||
if ( propertyInsertability && generator != null ) {
|
||||
final OnExecutionGenerator propertyGenerator = generator.getPropertyGenerator( propertyName );
|
||||
if ( propertyGenerator != null
|
||||
&& propertyGenerator.generatesOnInsert()
|
||||
&& !propertyGenerator.writePropertyValue() ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return propertyInsertability;
|
||||
}
|
||||
|
||||
private boolean isUpdatable(CompositeOnExecutionGenerator generator, boolean propertyUpdatability, String propertyName) {
|
||||
if ( propertyUpdatability && generator != null ) {
|
||||
final OnExecutionGenerator propertyGenerator = generator.getPropertyGenerator( propertyName );
|
||||
if ( propertyGenerator != null
|
||||
&& propertyGenerator.generatesOnUpdate()
|
||||
&& !propertyGenerator.writePropertyValue() ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return propertyUpdatability;
|
||||
}
|
||||
|
||||
private boolean isDefinedInClassOrSuperclass(Component bootDescriptor, String declaringClass, String subclass) {
|
||||
while ( subclass != null ) {
|
||||
if ( declaringClass.equals( subclass ) ) {
|
||||
|
@ -1121,4 +1155,25 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
|
|||
public boolean shouldBindAggregateMapping() {
|
||||
return preferBindAggregateMapping;
|
||||
}
|
||||
|
||||
private static CompositeOnExecutionGenerator resolveOnExecutionGenerator(EmbeddableValuedModelPart valueMapping) {
|
||||
if ( valueMapping instanceof EmbeddedAttributeMapping attributeMapping ) {
|
||||
if ( attributeMapping.getDeclaringType() instanceof EmbeddableMappingTypeImpl embeddableMappingType ) {
|
||||
if ( embeddableMappingType.getGenerator() instanceof CompositeOnExecutionGenerator compositeOnExecutionGenerator ) {
|
||||
if ( compositeOnExecutionGenerator.getPropertyGenerator( attributeMapping.getAttributeName() )
|
||||
instanceof CompositeOnExecutionGenerator composite ) {
|
||||
return composite;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( attributeMapping.getGenerator() instanceof CompositeOnExecutionGenerator compositeOnExecutionGenerator ) {
|
||||
return compositeOnExecutionGenerator;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Generator getGenerator() {
|
||||
return generator;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -408,6 +408,11 @@ public class EmbeddedAttributeMapping
|
|||
return producer.containsTableReference( tableExpression );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEntityIdentifierMapping() {
|
||||
return getAttributeMetadata() instanceof EmbeddedIdentifierMappingImpl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(Object value1, Object value2) {
|
||||
return embeddableMappingType.compare( value1, value2 );
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.hibernate.engine.spi.EntityKey;
|
|||
import org.hibernate.engine.spi.PersistenceContext;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.event.spi.MergeContext;
|
||||
import org.hibernate.generator.Generator;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
|
@ -332,4 +333,9 @@ public class InverseNonAggregatedIdentifierMapping extends EmbeddedAttributeMapp
|
|||
public Fetchable getFetchable(int position) {
|
||||
return getPartMappingType().getFetchable( position );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Generator getGenerator() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ package org.hibernate.metamodel.mapping.internal;
|
|||
|
||||
import org.hibernate.engine.FetchStyle;
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.generator.Generator;
|
||||
import org.hibernate.metamodel.mapping.AttributeMetadata;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
|
@ -97,4 +98,8 @@ public class VirtualEmbeddedAttributeMapping extends EmbeddedAttributeMapping im
|
|||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Generator getGenerator() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,22 +116,43 @@ public abstract class AbstractMutationCoordinator {
|
|||
}
|
||||
}
|
||||
|
||||
protected void handleValueGeneration(
|
||||
protected void handleInsertableValueGeneration(
|
||||
AttributeMapping attributeMapping,
|
||||
MutationGroupBuilder mutationGroupBuilder,
|
||||
OnExecutionGenerator generator) {
|
||||
final Dialect dialect = factory.getJdbcServices().getDialect();
|
||||
final boolean writePropertyValue = generator.writePropertyValue();
|
||||
final String[] columnValues = writePropertyValue ? null : generator.getReferencedColumnValues( dialect );
|
||||
attributeMapping.forEachSelectable( (j, mapping) -> {
|
||||
final String tableName = entityPersister.physicalTableNameForMutation( mapping );
|
||||
final ColumnValuesTableMutationBuilder tableUpdateBuilder = mutationGroupBuilder.findTableDetailsBuilder( tableName );
|
||||
tableUpdateBuilder.addValueColumn(
|
||||
mapping.getSelectionExpression(),
|
||||
writePropertyValue ? "?" : columnValues[j],
|
||||
mapping.getJdbcMapping(),
|
||||
mapping.isLob()
|
||||
);
|
||||
attributeMapping.forEachInsertable( (j, mapping) -> {
|
||||
final String tableName = entityPersister.physicalTableNameForMutation( mapping );
|
||||
final ColumnValuesTableMutationBuilder tableUpdateBuilder = mutationGroupBuilder.findTableDetailsBuilder(
|
||||
tableName );
|
||||
tableUpdateBuilder.addValueColumn(
|
||||
mapping.getSelectionExpression(),
|
||||
writePropertyValue ? "?" : columnValues[j],
|
||||
mapping.getJdbcMapping(),
|
||||
mapping.isLob()
|
||||
);
|
||||
} );
|
||||
}
|
||||
|
||||
protected void handleUpdatableValueGeneration(
|
||||
AttributeMapping attributeMapping,
|
||||
MutationGroupBuilder mutationGroupBuilder,
|
||||
OnExecutionGenerator generator) {
|
||||
final Dialect dialect = factory.getJdbcServices().getDialect();
|
||||
final boolean writePropertyValue = generator.writePropertyValue();
|
||||
final String[] columnValues = writePropertyValue ? null : generator.getReferencedColumnValues( dialect );
|
||||
attributeMapping.forEachUpdatable( (j, mapping) -> {
|
||||
final String tableName = entityPersister.physicalTableNameForMutation( mapping );
|
||||
final ColumnValuesTableMutationBuilder tableUpdateBuilder = mutationGroupBuilder.findTableDetailsBuilder(
|
||||
tableName );
|
||||
tableUpdateBuilder.addValueColumn(
|
||||
mapping.getSelectionExpression(),
|
||||
writePropertyValue ? "?" : columnValues[j],
|
||||
mapping.getJdbcMapping(),
|
||||
mapping.isLob()
|
||||
);
|
||||
} );
|
||||
}
|
||||
|
||||
|
|
|
@ -412,7 +412,10 @@ public class InsertCoordinatorStandard extends AbstractMutationCoordinator imple
|
|||
attributeMapping.forEachInsertable( insertGroupBuilder );
|
||||
}
|
||||
else if ( isValueGenerationInSql( generator, factory.getJdbcServices().getDialect() ) ) {
|
||||
handleValueGeneration( attributeMapping, insertGroupBuilder, (OnExecutionGenerator) generator );
|
||||
handleInsertableValueGeneration(
|
||||
attributeMapping,
|
||||
insertGroupBuilder,
|
||||
(OnExecutionGenerator) generator );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1220,7 +1220,7 @@ public class UpdateCoordinatorStandard extends AbstractMutationCoordinator imple
|
|||
SharedSessionContractImplementor session) {
|
||||
final Generator generator = attributeMapping.getGenerator();
|
||||
if ( needsValueGeneration( entity, session, generator ) ) {
|
||||
handleValueGeneration( attributeMapping, updateGroupBuilder, (OnExecutionGenerator) generator );
|
||||
handleUpdatableValueGeneration( attributeMapping, updateGroupBuilder, (OnExecutionGenerator) generator );
|
||||
}
|
||||
else if ( versionMapping != null
|
||||
&& versionMapping.getVersionAttribute() == attributeMapping) {
|
||||
|
|
|
@ -8,6 +8,7 @@ import org.hibernate.Internal;
|
|||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.generator.BeforeExecutionGenerator;
|
||||
import org.hibernate.generator.CompositeOnExecutionGenerator;
|
||||
import org.hibernate.generator.EventType;
|
||||
import org.hibernate.generator.Generator;
|
||||
import org.hibernate.generator.OnExecutionGenerator;
|
||||
|
@ -18,7 +19,9 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.lang.System.arraycopy;
|
||||
import static org.hibernate.generator.EventTypeSets.NONE;
|
||||
|
@ -35,7 +38,7 @@ class CompositeGeneratorBuilder {
|
|||
private boolean hadBeforeExecutionGeneration;
|
||||
private boolean hadOnExecutionGeneration;
|
||||
|
||||
private final List<Generator> generators = new ArrayList<>();
|
||||
private final Map<String,Generator> generatorsByPropertyName = new HashMap<>();
|
||||
|
||||
public CompositeGeneratorBuilder(String entityName, Property mappingProperty, Dialect dialect) {
|
||||
this.entityName = entityName;
|
||||
|
@ -43,8 +46,8 @@ class CompositeGeneratorBuilder {
|
|||
this.dialect = dialect;
|
||||
}
|
||||
|
||||
public void add(Generator generator) {
|
||||
generators.add( generator );
|
||||
public void add(String propertyName, Generator generator) {
|
||||
generatorsByPropertyName.put( propertyName, generator );
|
||||
|
||||
if ( generator != null && generator.generatesSometimes() ) {
|
||||
if ( generator.generatedOnExecution() ) {
|
||||
|
@ -76,7 +79,6 @@ class CompositeGeneratorBuilder {
|
|||
|
||||
private OnExecutionGenerator createCompositeOnExecutionGenerator() {
|
||||
final Component composite = (Component) mappingProperty.getValue();
|
||||
|
||||
// the base-line values for the aggregated OnExecutionGenerator we will build here.
|
||||
final EnumSet<EventType> eventTypes = EnumSet.noneOf(EventType.class);
|
||||
boolean referenceColumns = false;
|
||||
|
@ -87,50 +89,52 @@ class CompositeGeneratorBuilder {
|
|||
// start building the aggregate values
|
||||
int columnIndex = 0;
|
||||
final List<Property> properties = composite.getProperties();
|
||||
final Map<String, OnExecutionGenerator> generatorsByName = new HashMap<>(properties.size());
|
||||
for ( int i = 0; i < properties.size(); i++ ) {
|
||||
final Property property = properties.get(i);
|
||||
final OnExecutionGenerator generator = (OnExecutionGenerator) generators.get(i);
|
||||
if ( generator == null ) {
|
||||
throw new CompositeValueGenerationException(
|
||||
"Property of on-execution generated embeddable is not generated: "
|
||||
+ mappingProperty.getName() + '.' + property.getName()
|
||||
);
|
||||
}
|
||||
eventTypes.addAll( generator.getEventTypes() );
|
||||
if ( generator.referenceColumnsInSql( dialect ) ) {
|
||||
// override base-line value
|
||||
referenceColumns = true;
|
||||
final String[] referencedColumnValues = generator.getReferencedColumnValues( dialect );
|
||||
if ( referencedColumnValues != null ) {
|
||||
final int span = property.getColumnSpan();
|
||||
if ( referencedColumnValues.length != span ) {
|
||||
throw new CompositeValueGenerationException(
|
||||
"Mismatch between number of collected generated column values and number of columns for composite attribute: "
|
||||
+ mappingProperty.getName() + '.' + property.getName()
|
||||
);
|
||||
final String name = property.getName();
|
||||
final OnExecutionGenerator generator = (OnExecutionGenerator) generatorsByPropertyName.get( name );
|
||||
generatorsByName.put( name, generator );
|
||||
if ( generator != null ) {
|
||||
|
||||
eventTypes.addAll( generator.getEventTypes() );
|
||||
if ( generator.referenceColumnsInSql( dialect ) ) {
|
||||
// override base-line value
|
||||
referenceColumns = true;
|
||||
final String[] referencedColumnValues = generator.getReferencedColumnValues( dialect );
|
||||
if ( referencedColumnValues != null ) {
|
||||
final int span = property.getColumnSpan();
|
||||
if ( referencedColumnValues.length != span ) {
|
||||
throw new CompositeValueGenerationException(
|
||||
"Mismatch between number of collected generated column values and number of columns for composite attribute: "
|
||||
+ mappingProperty.getName() + '.' + name
|
||||
);
|
||||
}
|
||||
arraycopy( referencedColumnValues, 0, columnValues, columnIndex, span );
|
||||
columnIndex += span;
|
||||
}
|
||||
arraycopy( referencedColumnValues, 0, columnValues, columnIndex, span );
|
||||
columnIndex += span;
|
||||
}
|
||||
}
|
||||
if ( generator.writePropertyValue() ) {
|
||||
writable = true;
|
||||
}
|
||||
if ( generator.allowMutation() ) {
|
||||
mutable = true;
|
||||
if ( generator.writePropertyValue() ) {
|
||||
writable = true;
|
||||
}
|
||||
if ( generator.allowMutation() ) {
|
||||
mutable = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// then use the aggregated values to build an OnExecutionGenerator
|
||||
return new CompositeOnExecutionGenerator( eventTypes, referenceColumns, columnValues, writable, mutable );
|
||||
return new CompositeOnExecutionGeneratorImpl( eventTypes, generatorsByName, referenceColumns, columnValues, writable, mutable );
|
||||
}
|
||||
|
||||
private BeforeExecutionGenerator createCompositeBeforeExecutionGenerator() {
|
||||
final Component composite = (Component) mappingProperty.getValue();
|
||||
final EnumSet<EventType> eventTypes = EnumSet.noneOf(EventType.class);
|
||||
final List<Property> properties = composite.getProperties();
|
||||
final List<Generator> generators = new ArrayList<>(properties.size());
|
||||
for ( int i = 0; i < properties.size(); i++ ) {
|
||||
final Generator generator = generators.get(i);
|
||||
final Generator generator = generatorsByPropertyName.get( properties.get( i ).getName() );
|
||||
generators.add( generator );
|
||||
if ( generator != null ) {
|
||||
eventTypes.addAll( generator.getEventTypes() );
|
||||
}
|
||||
|
@ -138,13 +142,14 @@ class CompositeGeneratorBuilder {
|
|||
return new CompositeBeforeExecutionGenerator( entityName, generators, mappingProperty, properties, eventTypes );
|
||||
}
|
||||
|
||||
private record CompositeOnExecutionGenerator(
|
||||
public record CompositeOnExecutionGeneratorImpl(
|
||||
EnumSet<EventType> eventTypes,
|
||||
Map<String,OnExecutionGenerator> generatedPropertiesByName,
|
||||
boolean referenceColumnsInSql,
|
||||
String[] columnValues,
|
||||
boolean writePropertyValue,
|
||||
boolean allowMutation)
|
||||
implements OnExecutionGenerator {
|
||||
implements CompositeOnExecutionGenerator {
|
||||
@Override
|
||||
public boolean referenceColumnsInSql(Dialect dialect) {
|
||||
return referenceColumnsInSql;
|
||||
|
@ -158,6 +163,11 @@ class CompositeGeneratorBuilder {
|
|||
public EnumSet<EventType> getEventTypes() {
|
||||
return eventTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OnExecutionGenerator getPropertyGenerator(String propertyName) {
|
||||
return generatedPropertiesByName.get( propertyName );
|
||||
}
|
||||
}
|
||||
|
||||
private record CompositeBeforeExecutionGenerator(
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.hibernate.engine.spi.CascadeStyle;
|
|||
import org.hibernate.engine.spi.CascadeStyles;
|
||||
import org.hibernate.engine.spi.CascadingActions;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.generator.CompositeOnExecutionGenerator;
|
||||
import org.hibernate.generator.Generator;
|
||||
import org.hibernate.generator.OnExecutionGenerator;
|
||||
import org.hibernate.generator.BeforeExecutionGenerator;
|
||||
|
@ -328,7 +329,7 @@ public class EntityMetamodel implements Serializable {
|
|||
propertyCheckability[i] = false;
|
||||
}
|
||||
if ( generator.generatesOnInsert() ) {
|
||||
if ( generatedOnExecution ) {
|
||||
if ( generatedOnExecution && !(generator instanceof CompositeOnExecutionGenerator) ) {
|
||||
propertyInsertability[i] = writePropertyValue( (OnExecutionGenerator) generator );
|
||||
}
|
||||
foundPostInsertGeneratedValues = foundPostInsertGeneratedValues
|
||||
|
@ -340,7 +341,7 @@ public class EntityMetamodel implements Serializable {
|
|||
propertyInsertability[i] = false;
|
||||
}
|
||||
if ( generator.generatesOnUpdate() ) {
|
||||
if ( generatedOnExecution ) {
|
||||
if ( generatedOnExecution && !(generator instanceof CompositeOnExecutionGenerator) ) {
|
||||
propertyUpdateability[i] = writePropertyValue( (OnExecutionGenerator) generator );
|
||||
}
|
||||
foundPostUpdateGeneratedValues = foundPostUpdateGeneratedValues
|
||||
|
@ -529,20 +530,25 @@ public class EntityMetamodel implements Serializable {
|
|||
final Property mappingProperty,
|
||||
final RuntimeModelCreationContext context) {
|
||||
final GeneratorCreator generatorCreator = mappingProperty.getValueGeneratorCreator();
|
||||
if ( mappingProperty.getValue() instanceof Component component ) {
|
||||
final CompositeGeneratorBuilder builder =
|
||||
new CompositeGeneratorBuilder( entityName, mappingProperty, context.getDialect() );
|
||||
for ( Property property : component.getProperties() ) {
|
||||
if ( property.getValue() instanceof Component ) {
|
||||
builder.add( property.getName(), buildGenerator( entityName, property, context ) );
|
||||
}
|
||||
else {
|
||||
builder.add( property.getName(), property.createGenerator( context ) );
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
if ( generatorCreator != null ) {
|
||||
final Generator generator = mappingProperty.createGenerator( context );
|
||||
if ( generator.generatesSometimes() ) {
|
||||
return generator;
|
||||
}
|
||||
}
|
||||
if ( mappingProperty.getValue() instanceof Component component ) {
|
||||
final CompositeGeneratorBuilder builder =
|
||||
new CompositeGeneratorBuilder( entityName, mappingProperty, context.getDialect() );
|
||||
for ( Property property : component.getProperties() ) {
|
||||
builder.add( property.createGenerator( context ) );
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue