Skip to content

Commit f41d926

Browse files
author
nathan.xu
committed
HHH-19320 Fix defect that currentValue parameter is still null in BeforeExecutionGenerator#generate() when id allowed to be assigned and was assigned
1 parent ba1da93 commit f41d926

File tree

2 files changed

+83
-1
lines changed

2 files changed

+83
-1
lines changed

hibernate-core/src/main/java/org/hibernate/event/internal/AbstractSaveEventListener.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ else if ( !generator.generatesOnInsert() ) {
114114
// the @PrePersist callback to happen first
115115
generatedId = null;
116116
}
117-
else if ( generatedBeforeExecution ) {
117+
else if ( generatedBeforeExecution && ( ! generator.allowAssignedIdentifiers() || persister.getIdentifier( entity, source ) == null ) ) {
118118
// go ahead and generate id, and then set it to
119119
// the entity instance, so it will be available
120120
// to the entity in the @PrePersist callback
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.orm.test.idgen.userdefined;
6+
7+
import jakarta.persistence.Entity;
8+
import jakarta.persistence.GeneratedValue;
9+
import jakarta.persistence.Id;
10+
import jakarta.persistence.Table;
11+
import org.hibernate.annotations.IdGeneratorType;
12+
import org.hibernate.annotations.ValueGenerationType;
13+
import org.hibernate.engine.spi.SharedSessionContractImplementor;
14+
import org.hibernate.generator.BeforeExecutionGenerator;
15+
import org.hibernate.generator.EventType;
16+
import org.hibernate.testing.orm.junit.DomainModel;
17+
import org.hibernate.testing.orm.junit.SessionFactory;
18+
import org.hibernate.testing.orm.junit.SessionFactoryScope;
19+
import org.junit.jupiter.api.Test;
20+
21+
import java.lang.annotation.Retention;
22+
import java.lang.annotation.Target;
23+
import java.util.EnumSet;
24+
import java.util.UUID;
25+
26+
import static java.lang.annotation.ElementType.FIELD;
27+
import static java.lang.annotation.ElementType.METHOD;
28+
import static java.lang.annotation.RetentionPolicy.RUNTIME;
29+
import static org.assertj.core.api.Assertions.assertThat;
30+
31+
@SessionFactory
32+
@DomainModel(annotatedClasses = BeforeExecutionGeneratorWithAssignedIdentifiersTest.Book.class)
33+
class BeforeExecutionGeneratorWithAssignedIdentifiersTest {
34+
35+
@Test
36+
void testAssignedValueNotOverridden(SessionFactoryScope scope) {
37+
final String assignedId = "assigned-id";
38+
final Book book = new Book();
39+
book.id = assignedId;
40+
scope.inTransaction( session -> session.persist( book ) );
41+
assertThat( book.id ).isEqualTo( assignedId );
42+
}
43+
44+
@Entity
45+
@Table(name = "books")
46+
static class Book {
47+
@Id @GeneratedValue
48+
@AssignableIdGenerator
49+
String id;
50+
}
51+
52+
@IdGeneratorType(IdGenerator.class)
53+
@ValueGenerationType(generatedBy = IdGenerator.class)
54+
@Retention(RUNTIME)
55+
@Target({FIELD, METHOD})
56+
public @interface AssignableIdGenerator {}
57+
58+
public static class IdGenerator implements BeforeExecutionGenerator {
59+
60+
@Override
61+
public Object generate(
62+
SharedSessionContractImplementor session,
63+
Object owner,
64+
Object currentValue,
65+
EventType eventType) {
66+
if ( currentValue != null ) {
67+
return currentValue;
68+
}
69+
return UUID.randomUUID().toString();
70+
}
71+
72+
@Override
73+
public EnumSet<EventType> getEventTypes() {
74+
return EnumSet.of( EventType.INSERT );
75+
}
76+
77+
@Override
78+
public boolean allowAssignedIdentifiers() {
79+
return true;
80+
}
81+
}
82+
}

0 commit comments

Comments
 (0)