Skip to content

Commit 810842a

Browse files
committed
HHH-18679 Allow @Generated(writable=true) with assigned identifiers
1 parent 7b81b4d commit 810842a

File tree

2 files changed

+40
-6
lines changed

2 files changed

+40
-6
lines changed

hibernate-core/src/main/java/org/hibernate/generator/internal/GeneratedGeneration.java

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@
66

77
import org.hibernate.annotations.Generated;
88
import org.hibernate.dialect.Dialect;
9+
import org.hibernate.engine.spi.SharedSessionContractImplementor;
10+
import org.hibernate.generator.BeforeExecutionGenerator;
911
import org.hibernate.generator.EventType;
1012
import org.hibernate.generator.OnExecutionGenerator;
13+
import org.hibernate.persister.entity.EntityPersister;
1114

1215
import java.util.EnumSet;
1316

@@ -23,7 +26,7 @@
2326
* @author Steve Ebersole
2427
* @author Gunnar Morling
2528
*/
26-
public class GeneratedGeneration implements OnExecutionGenerator {
29+
public class GeneratedGeneration implements OnExecutionGenerator, BeforeExecutionGenerator {
2730

2831
private final EnumSet<EventType> eventTypes;
2932
private final boolean writable;
@@ -60,4 +63,32 @@ public String[] getReferencedColumnValues(Dialect dialect) {
6063
public boolean writePropertyValue() {
6164
return writable && sql==null;
6265
}
66+
67+
@Override
68+
public boolean generatedOnExecution() {
69+
return true;
70+
}
71+
72+
@Override
73+
public boolean generatedOnExecution(Object entity, SharedSessionContractImplementor session) {
74+
if ( !writable ) {
75+
return true;
76+
}
77+
78+
// When this is the identifier generator and writable is true, allow pre-assigned identifiers
79+
final EntityPersister entityPersister = session.getEntityPersister( null, entity );
80+
return entityPersister.getGenerator() != this || entityPersister.getIdentifier( entity, session ) == null;
81+
}
82+
83+
@Override
84+
public Object generate(SharedSessionContractImplementor session, Object owner, Object currentValue, EventType eventType) {
85+
final EntityPersister entityPersister = session.getEntityPersister( null, owner );
86+
assert entityPersister.getGenerator() == this;
87+
return entityPersister.getIdentifier( owner, session );
88+
}
89+
90+
@Override
91+
public boolean allowAssignedIdentifiers() {
92+
return writable;
93+
}
6394
}

hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/InsertCoordinatorStandard.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.hibernate.generator.OnExecutionGenerator;
2525
import org.hibernate.generator.values.GeneratedValues;
2626
import org.hibernate.generator.values.GeneratedValuesMutationDelegate;
27+
import org.hibernate.id.IdentifierGenerationException;
2728
import org.hibernate.metamodel.mapping.AttributeMapping;
2829
import org.hibernate.metamodel.mapping.AttributeMappingsList;
2930
import org.hibernate.metamodel.mapping.BasicEntityIdentifierMapping;
@@ -433,11 +434,13 @@ else if ( isValueGenerationInSql( generator, factory.getJdbcServices().getDialec
433434
if ( generator.referenceColumnsInSql( dialect ) ) {
434435
final BasicEntityIdentifierMapping identifierMapping = (BasicEntityIdentifierMapping) entityPersister().getIdentifierMapping();
435436
final String[] columnValues = generator.getReferencedColumnValues( dialect );
436-
tableMapping.getKeyMapping().forEachKeyColumn( (i, column) -> tableInsertBuilder.addKeyColumn(
437-
column.getColumnName(),
438-
columnValues[i],
439-
identifierMapping.getJdbcMapping()
440-
) );
437+
if ( columnValues != null ) {
438+
tableMapping.getKeyMapping().forEachKeyColumn( (i, column) -> tableInsertBuilder.addKeyColumn(
439+
column.getColumnName(),
440+
columnValues[i],
441+
identifierMapping.getJdbcMapping()
442+
) );
443+
}
441444
}
442445
}
443446
else {

0 commit comments

Comments
 (0)