Skip to content

Commit f80b907

Browse files
yrodierebeikov
authored andcommitted
HHH-16461 Test @Version + session.refresh(entity, LockMode.PESSIMISTIC_WRITE)
1 parent 2a504ef commit f80b907

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package org.hibernate.orm.test.locking;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import java.util.stream.Stream;
6+
7+
import org.hibernate.LockMode;
8+
9+
import org.hibernate.testing.TestForIssue;
10+
import org.hibernate.testing.orm.junit.DomainModel;
11+
import org.hibernate.testing.orm.junit.SessionFactory;
12+
import org.hibernate.testing.orm.junit.SessionFactoryScope;
13+
import org.junit.jupiter.params.ParameterizedTest;
14+
import org.junit.jupiter.params.provider.MethodSource;
15+
16+
import jakarta.persistence.Entity;
17+
import jakarta.persistence.GeneratedValue;
18+
import jakarta.persistence.Id;
19+
import jakarta.persistence.Version;
20+
21+
@DomainModel(annotatedClasses = {
22+
OptimisticAndPessimisticLockTest.EntityA.class
23+
})
24+
@SessionFactory
25+
@TestForIssue(jiraKey = "HHH-16461")
26+
public class OptimisticAndPessimisticLockTest {
27+
28+
public Stream<LockMode> pessimisticLockModes() {
29+
return Stream.of(LockMode.UPGRADE_NOWAIT, LockMode.PESSIMISTIC_WRITE, LockMode.PESSIMISTIC_READ, LockMode.PESSIMISTIC_FORCE_INCREMENT);
30+
}
31+
32+
@ParameterizedTest
33+
@MethodSource(value = "pessimisticLockModes")
34+
public void upgradeFromOptimisticToPessimisticLock(LockMode pessimisticLockMode, SessionFactoryScope scope) {
35+
Integer id = scope.fromTransaction( session -> {
36+
EntityA entityA1 = new EntityA();
37+
entityA1.setPropertyA( 1 );
38+
session.persist( entityA1 );
39+
return entityA1.getId();
40+
} );
41+
scope.inTransaction( session -> {
42+
EntityA entityA1 = session.find( EntityA.class, id );
43+
44+
// Do a concurrent change that will update the @Version property
45+
scope.inTransaction( session2 -> {
46+
var concurrentEntityA1 = session2.find( EntityA.class, id );
47+
concurrentEntityA1.setPropertyA( concurrentEntityA1.getPropertyA() + 1 );
48+
} );
49+
50+
// Refresh the entity with concurrent changes and upgrade the lock
51+
session.refresh( entityA1, pessimisticLockMode );
52+
53+
entityA1.setPropertyA( entityA1.getPropertyA() * 2 );
54+
} );
55+
scope.inTransaction( session -> {
56+
EntityA entityA1 = session.find( EntityA.class, id );
57+
assertThat( entityA1.getPropertyA() ).isEqualTo( ( 1 + 1 ) * 2 );
58+
} );
59+
}
60+
61+
@Entity(name = "EntityA")
62+
public static class EntityA {
63+
64+
@Id
65+
@GeneratedValue
66+
Integer id;
67+
68+
@Version
69+
long version;
70+
71+
int propertyA;
72+
73+
public EntityA() {
74+
}
75+
76+
public EntityA(Integer id) {
77+
this.id = id;
78+
}
79+
80+
public Integer getId() {
81+
return id;
82+
}
83+
84+
public long getVersion() {
85+
return version;
86+
}
87+
88+
public int getPropertyA() {
89+
return propertyA;
90+
}
91+
92+
public void setPropertyA(int propertyA) {
93+
this.propertyA = propertyA;
94+
}
95+
}
96+
}

0 commit comments

Comments
 (0)