Skip to content

Commit d27765f

Browse files
committed
HHH-19522 report failed optimistic lock checking for upsert()
upsert() should throw StaleObjectStateException if the version verification fails
1 parent 12118ee commit d27765f

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

hibernate-core/src/main/java/org/hibernate/sql/model/jdbc/MergeOperation.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public MergeOperation(
2323
MutationTarget<?> mutationTarget,
2424
String sql,
2525
List<? extends JdbcParameterBinder> parameterBinders) {
26-
super( tableDetails, mutationTarget, sql, false, Expectation.None.INSTANCE, parameterBinders );
26+
super( tableDetails, mutationTarget, sql, false, new Expectation.RowCount(), parameterBinders );
2727
}
2828

2929
@Override

hibernate-core/src/test/java/org/hibernate/orm/test/stateless/UpsertVersionedTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,21 @@
77
import jakarta.persistence.Entity;
88
import jakarta.persistence.Id;
99
import jakarta.persistence.Version;
10+
import org.hibernate.StaleObjectStateException;
1011
import org.hibernate.testing.orm.junit.DomainModel;
1112
import org.hibernate.testing.orm.junit.SessionFactory;
1213
import org.hibernate.testing.orm.junit.SessionFactoryScope;
1314
import org.junit.jupiter.api.Test;
1415

1516
import static org.junit.jupiter.api.Assertions.assertEquals;
17+
import static org.junit.jupiter.api.Assertions.fail;
1618

1719
@SessionFactory
1820
@DomainModel(annotatedClasses = UpsertVersionedTest.Record.class)
1921
public class UpsertVersionedTest {
22+
2023
@Test void test(SessionFactoryScope scope) {
24+
scope.getSessionFactory().getSchemaManager().truncate();
2125
scope.inStatelessTransaction(s-> {
2226
s.upsert(new Record(123L,null,"hello earth"));
2327
s.upsert(new Record(456L,2L,"hello mars"));
@@ -41,6 +45,29 @@ public class UpsertVersionedTest {
4145
assertEquals( "goodbye mars", s.get( Record.class,456L).message );
4246
});
4347
}
48+
49+
@Test void testStaleUpsert(SessionFactoryScope scope) {
50+
scope.getSessionFactory().getSchemaManager().truncate();
51+
scope.inStatelessTransaction( s -> {
52+
s.insert(new Record(789L, 1L, "hello world"));
53+
} );
54+
scope.inStatelessTransaction( s -> {
55+
s.upsert(new Record(789L, 1L, "hello mars"));
56+
} );
57+
try {
58+
scope.inStatelessTransaction( s -> {
59+
s.upsert(new Record( 789L, 1L, "hello venus"));
60+
} );
61+
fail();
62+
}
63+
catch (StaleObjectStateException sose) {
64+
//expected
65+
}
66+
scope.inStatelessTransaction( s-> {
67+
assertEquals( "hello mars", s.get(Record.class,789L).message );
68+
} );
69+
}
70+
4471
@Entity(name = "Record")
4572
static class Record {
4673
@Id Long id;

0 commit comments

Comments
 (0)