Skip to content

Commit 0c1a080

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

File tree

2 files changed

+86
-1
lines changed

2 files changed

+86
-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,85 @@
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+
var assignedId = "assigned-id";
38+
var book = new Book();
39+
book.id = assignedId;
40+
scope.inTransaction( session -> {
41+
session.persist( book );
42+
} );
43+
assertThat(book.id).isEqualTo( assignedId );
44+
}
45+
46+
@Entity
47+
@Table(name = "books")
48+
static class Book {
49+
@Id
50+
@GeneratedValue
51+
@AssignableIdGenerator
52+
String id;
53+
}
54+
55+
@IdGeneratorType(IdGenerator.class)
56+
@ValueGenerationType(generatedBy = IdGenerator.class)
57+
@Retention(RUNTIME)
58+
@Target({FIELD, METHOD})
59+
public @interface AssignableIdGenerator {}
60+
61+
public static class IdGenerator implements BeforeExecutionGenerator {
62+
63+
@Override
64+
public Object generate(
65+
SharedSessionContractImplementor session,
66+
Object owner,
67+
Object currentValue,
68+
EventType eventType) {
69+
if (currentValue != null) {
70+
return currentValue;
71+
}
72+
return UUID.randomUUID().toString();
73+
}
74+
75+
@Override
76+
public EnumSet<EventType> getEventTypes() {
77+
return EnumSet.of( EventType.INSERT );
78+
}
79+
80+
@Override
81+
public boolean allowAssignedIdentifiers() {
82+
return true;
83+
}
84+
}
85+
}

0 commit comments

Comments
 (0)