Skip to content

Commit 5054a72

Browse files
committed
HHH-16957 Embeddable cannot have only one @generated field HHH-18756 Embedded class with @CurrentTimestamp annotated property issue
1 parent bab5fa3 commit 5054a72

11 files changed

+278
-66
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/*
2+
* SPDX-License-Identifier: LGPL-2.1-or-later
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.generator;
6+
7+
public interface CompositeOnExecutionGenerator extends OnExecutionGenerator {
8+
OnExecutionGenerator getPropertyGenerator(String propertyName);
9+
boolean[] writePropertyValues();
10+
11+
}

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractSingularAttributeMapping.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public abstract class AbstractSingularAttributeMapping
2020
extends AbstractStateArrayContributorMapping
2121
implements SingularAttributeMapping {
2222

23+
private Generator generator;
24+
2325
public AbstractSingularAttributeMapping(
2426
String name,
2527
int stateArrayPosition,
@@ -52,7 +54,20 @@ protected AbstractSingularAttributeMapping( AbstractSingularAttributeMapping ori
5254

5355
@Override
5456
public Generator getGenerator() {
55-
return findContainingEntityMapping().getEntityPersister().getEntityMetamodel().getGenerators()[getStateArrayPosition()];
57+
if ( generator != null ) {
58+
return generator;
59+
}
60+
final int stateArrayPosition = getStateArrayPosition();
61+
if ( stateArrayPosition < 0 ) {
62+
return null;
63+
}
64+
final Generator[] generators = findContainingEntityMapping().getEntityPersister().getEntityMetamodel()
65+
.getGenerators();
66+
if ( generators.length == 0 ) {
67+
return null;
68+
}
69+
generator = generators[stateArrayPosition];
70+
return generator;
5671
}
5772

5873
}

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddableMappingTypeImpl.java

Lines changed: 67 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
import org.hibernate.engine.jdbc.spi.JdbcServices;
2525
import org.hibernate.engine.spi.CascadeStyle;
2626
import org.hibernate.engine.spi.SharedSessionContractImplementor;
27+
import org.hibernate.generator.CompositeOnExecutionGenerator;
28+
import org.hibernate.generator.Generator;
29+
import org.hibernate.generator.OnExecutionGenerator;
2730
import org.hibernate.mapping.AggregateColumn;
2831
import org.hibernate.mapping.Any;
2932
import org.hibernate.mapping.BasicValue;
@@ -171,6 +174,7 @@ public static EmbeddableMappingTypeImpl from(
171174
private final boolean aggregateMappingRequiresColumnWriter;
172175
private final boolean preferSelectAggregateMapping;
173176
private final boolean preferBindAggregateMapping;
177+
private final CompositeOnExecutionGenerator generator;
174178

175179
private EmbeddableMappingTypeImpl(
176180
Component bootDescriptor,
@@ -251,6 +255,7 @@ private EmbeddableMappingTypeImpl(
251255
this.preferSelectAggregateMapping = false;
252256
this.preferBindAggregateMapping = false;
253257
}
258+
this.generator = resolveOnExecutionGenerator( valueMapping );
254259
}
255260

256261
private JdbcMapping resolveJdbcMapping(Component bootDescriptor, RuntimeModelCreationContext creationContext) {
@@ -371,6 +376,7 @@ public EmbeddableMappingTypeImpl(
371376
attributeMappings
372377
)
373378
);
379+
this.generator = resolveOnExecutionGenerator( valueMapping );
374380
}
375381

376382
public EmbeddableMappingType createInverseMappingType(
@@ -436,13 +442,17 @@ private boolean finishInitialization(
436442

437443
// Reset the attribute mappings that were added in previous attempts
438444
attributeMappings.clear();
439-
440445
for ( final Property bootPropertyDescriptor : bootDescriptor.getProperties() ) {
446+
441447
final AttributeMapping attributeMapping;
442448

443449
final Type subtype = subtypes[attributeIndex];
444450
final Value value = bootPropertyDescriptor.getValue();
451+
final String name = bootPropertyDescriptor.getName();
445452
if ( subtype instanceof BasicType ) {
453+
boolean isInsertable = isInsertable( generator, insertability[columnPosition], name );
454+
boolean isUpdatable = isUpdatable( generator, updateability[columnPosition], name );
455+
446456
final BasicValue basicValue = (BasicValue) value;
447457
final Selectable selectable = dependantValue != null ?
448458
dependantValue.getColumns().get( dependantColumnIndex + columnPosition ) :
@@ -474,7 +484,7 @@ private boolean finishInitialization(
474484
containingTableExpression = rootTableExpression;
475485
columnExpression = rootTableKeyColumnNames[columnPosition];
476486
}
477-
final NavigableRole role = valueMapping.getNavigableRole().append( bootPropertyDescriptor.getName() );
487+
final NavigableRole role = valueMapping.getNavigableRole().append( name );
478488
final SelectablePath selectablePath;
479489
final String columnDefinition;
480490
final Long length;
@@ -502,10 +512,10 @@ private boolean finishInitialization(
502512
temporalPrecision = null;
503513
isLob = false;
504514
nullable = bootPropertyDescriptor.isOptional();
505-
selectablePath = new SelectablePath( determineEmbeddablePrefix() + bootPropertyDescriptor.getName() );
515+
selectablePath = new SelectablePath( determineEmbeddablePrefix() + name );
506516
}
507517
attributeMapping = MappingModelCreationHelper.buildBasicAttributeMapping(
508-
bootPropertyDescriptor.getName(),
518+
name,
509519
role,
510520
attributeIndex,
511521
attributeIndex,
@@ -525,8 +535,8 @@ private boolean finishInitialization(
525535
temporalPrecision,
526536
isLob,
527537
nullable,
528-
insertability[columnPosition],
529-
updateability[columnPosition],
538+
isInsertable,
539+
isUpdatable,
530540
representationStrategy.resolvePropertyAccess( bootPropertyDescriptor ),
531541
compositeType.getCascadeStyle( attributeIndex ),
532542
creationProcess
@@ -556,7 +566,7 @@ else if ( subtype instanceof AnyType anyType ) {
556566
);
557567

558568
attributeMapping = new DiscriminatedAssociationAttributeMapping(
559-
valueMapping.getNavigableRole().append( bootPropertyDescriptor.getName() ),
569+
valueMapping.getNavigableRole().append( name ),
560570
typeConfiguration.getJavaTypeRegistry().getDescriptor( Object.class ),
561571
this,
562572
attributeIndex,
@@ -585,7 +595,7 @@ else if ( subtype instanceof CompositeType subCompositeType ) {
585595
}
586596

587597
attributeMapping = MappingModelCreationHelper.buildEmbeddedAttributeMapping(
588-
bootPropertyDescriptor.getName(),
598+
name,
589599
attributeIndex,
590600
attributeIndex,
591601
bootPropertyDescriptor,
@@ -604,7 +614,7 @@ else if ( subtype instanceof CompositeType subCompositeType ) {
604614
}
605615
else if ( subtype instanceof CollectionType ) {
606616
attributeMapping = MappingModelCreationHelper.buildPluralAttributeMapping(
607-
bootPropertyDescriptor.getName(),
617+
name,
608618
attributeIndex,
609619
attributeIndex,
610620
bootPropertyDescriptor,
@@ -619,8 +629,8 @@ else if ( subtype instanceof EntityType ) {
619629
final EntityPersister entityPersister = creationProcess.getEntityPersister( bootDescriptor.getOwner().getEntityName() );
620630

621631
attributeMapping = MappingModelCreationHelper.buildSingularAssociationAttributeMapping(
622-
bootPropertyDescriptor.getName(),
623-
valueMapping.getNavigableRole().append( bootPropertyDescriptor.getName() ),
632+
name,
633+
valueMapping.getNavigableRole().append( name ),
624634
attributeIndex,
625635
attributeIndex,
626636
bootPropertyDescriptor,
@@ -639,7 +649,7 @@ else if ( subtype instanceof EntityType ) {
639649
Locale.ROOT,
640650
"Unable to determine attribute nature : %s#%s",
641651
bootDescriptor.getOwner().getEntityName(),
642-
bootPropertyDescriptor.getName()
652+
name
643653
)
644654
);
645655
}
@@ -667,6 +677,30 @@ else if ( subtype instanceof EntityType ) {
667677
return true;
668678
}
669679

680+
private boolean isInsertable(CompositeOnExecutionGenerator generator, boolean propertyInsertability, String propertyName) {
681+
if ( propertyInsertability && generator != null ) {
682+
final OnExecutionGenerator propertyGenerator = generator.getPropertyGenerator( propertyName );
683+
if ( propertyGenerator != null
684+
&& propertyGenerator.generatesOnInsert()
685+
&& !propertyGenerator.writePropertyValue() ) {
686+
return false;
687+
}
688+
}
689+
return propertyInsertability;
690+
}
691+
692+
private boolean isUpdatable(CompositeOnExecutionGenerator generator, boolean propertyUpdatability, String propertyName) {
693+
if ( propertyUpdatability && generator != null ) {
694+
final OnExecutionGenerator propertyGenerator = generator.getPropertyGenerator( propertyName );
695+
if ( propertyGenerator != null
696+
&& propertyGenerator.generatesOnUpdate()
697+
&& !propertyGenerator.writePropertyValue() ) {
698+
return false;
699+
}
700+
}
701+
return propertyUpdatability;
702+
}
703+
670704
private boolean isDefinedInClassOrSuperclass(Component bootDescriptor, String declaringClass, String subclass) {
671705
while ( subclass != null ) {
672706
if ( declaringClass.equals( subclass ) ) {
@@ -1121,4 +1155,25 @@ public boolean shouldSelectAggregateMapping() {
11211155
public boolean shouldBindAggregateMapping() {
11221156
return preferBindAggregateMapping;
11231157
}
1158+
1159+
private static CompositeOnExecutionGenerator resolveOnExecutionGenerator(EmbeddableValuedModelPart valueMapping) {
1160+
if ( valueMapping instanceof EmbeddedAttributeMapping attributeMapping ) {
1161+
if ( attributeMapping.getDeclaringType() instanceof EmbeddableMappingTypeImpl embeddableMappingType ) {
1162+
if ( embeddableMappingType.getGenerator() instanceof CompositeOnExecutionGenerator compositeOnExecutionGenerator ) {
1163+
if ( compositeOnExecutionGenerator.getPropertyGenerator( attributeMapping.getAttributeName() )
1164+
instanceof CompositeOnExecutionGenerator composite ) {
1165+
return composite;
1166+
}
1167+
}
1168+
}
1169+
else if ( attributeMapping.getGenerator() instanceof CompositeOnExecutionGenerator compositeOnExecutionGenerator ) {
1170+
return compositeOnExecutionGenerator;
1171+
}
1172+
}
1173+
return null;
1174+
}
1175+
1176+
public Generator getGenerator() {
1177+
return generator;
1178+
}
11241179
}

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedAttributeMapping.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,11 @@ public boolean containsTableReference(String tableExpression) {
408408
return producer.containsTableReference( tableExpression );
409409
}
410410

411+
@Override
412+
public boolean isEntityIdentifierMapping() {
413+
return getAttributeMetadata() instanceof EmbeddedIdentifierMappingImpl;
414+
}
415+
411416
@Override
412417
public int compare(Object value1, Object value2) {
413418
return embeddableMappingType.compare( value1, value2 );

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/InverseNonAggregatedIdentifierMapping.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import org.hibernate.engine.spi.PersistenceContext;
1414
import org.hibernate.engine.spi.SharedSessionContractImplementor;
1515
import org.hibernate.event.spi.MergeContext;
16+
import org.hibernate.generator.Generator;
1617
import org.hibernate.internal.util.collections.CollectionHelper;
1718
import org.hibernate.metamodel.mapping.AttributeMapping;
1819
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
@@ -332,4 +333,9 @@ public int getNumberOfFetchables() {
332333
public Fetchable getFetchable(int position) {
333334
return getPartMappingType().getFetchable( position );
334335
}
336+
337+
@Override
338+
public Generator getGenerator() {
339+
return null;
340+
}
335341
}

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/VirtualEmbeddedAttributeMapping.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import org.hibernate.engine.FetchStyle;
88
import org.hibernate.engine.FetchTiming;
9+
import org.hibernate.generator.Generator;
910
import org.hibernate.metamodel.mapping.AttributeMetadata;
1011
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
1112
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
@@ -97,4 +98,8 @@ public VirtualEmbeddedAttributeMapping(
9798
);
9899
}
99100

101+
@Override
102+
public Generator getGenerator() {
103+
return null;
104+
}
100105
}

0 commit comments

Comments
 (0)