Skip to content

Commit 52ba0ce

Browse files
committed
HHH-9127 Add test showing forceIncrement leaves stale data in transactional cache
1 parent 227caea commit 52ba0ce

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/*
2+
* SPDX-License-Identifier: LGPL-2.1-or-later
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.orm.test.cache;
6+
7+
import jakarta.persistence.Cacheable;
8+
import jakarta.persistence.Entity;
9+
import jakarta.persistence.Id;
10+
import jakarta.persistence.LockModeType;
11+
import jakarta.persistence.Version;
12+
import org.hibernate.LockMode;
13+
import org.hibernate.annotations.Cache;
14+
import org.hibernate.annotations.CacheConcurrencyStrategy;
15+
import org.hibernate.testing.orm.junit.DomainModel;
16+
import org.hibernate.testing.orm.junit.Jira;
17+
import org.hibernate.testing.orm.junit.SessionFactory;
18+
import org.hibernate.testing.orm.junit.SessionFactoryScope;
19+
import org.junit.jupiter.api.AfterEach;
20+
import org.junit.jupiter.api.BeforeEach;
21+
import org.junit.jupiter.api.Test;
22+
23+
import static org.assertj.core.api.Assertions.assertThat;
24+
25+
@SessionFactory
26+
@DomainModel(annotatedClasses = {
27+
ForceIncrementCacheTest.Person.class
28+
})
29+
@Jira("https://hibernate.atlassian.net/browse/HHH-9127")
30+
public class ForceIncrementCacheTest {
31+
32+
@BeforeEach
33+
public void setUp(SessionFactoryScope scope) {
34+
scope.inTransaction( session -> {
35+
session.persist( new Person( 1L, "Marco" ) );
36+
} );
37+
}
38+
39+
@AfterEach
40+
public void tearDown(SessionFactoryScope scope) {
41+
scope.inTransaction( session -> {
42+
session.createMutationQuery( "delete from Person" ).executeUpdate();
43+
} );
44+
}
45+
46+
@Test
47+
public void testOptimisticForceIncrementOnLoad(SessionFactoryScope scope) {
48+
scope.inTransaction( session -> {
49+
Person entity = session.find( Person.class, 1L, LockModeType.OPTIMISTIC_FORCE_INCREMENT );
50+
assertThat( entity.getVersion() ).isEqualTo( 0L );
51+
} );
52+
// in a different transaction
53+
scope.inTransaction( session -> {
54+
Person entity = session.find( Person.class, 1L );
55+
assertThat( entity.getVersion() ).isEqualTo( 1L );
56+
} );
57+
}
58+
59+
@Test
60+
public void testPessimisticForceIncrementOnLoad(SessionFactoryScope scope) {
61+
scope.inTransaction( session -> {
62+
Person entity = session.find( Person.class, 1L );
63+
assertThat( entity.getVersion() ).isEqualTo( 0L );
64+
} );
65+
scope.inTransaction( session -> {
66+
Person entity = session.find( Person.class, 1L, LockModeType.PESSIMISTIC_FORCE_INCREMENT );
67+
assertThat( entity.getVersion() ).isEqualTo( 1L );
68+
} );
69+
// in a different transaction
70+
scope.inTransaction( session -> {
71+
Person entity = session.find( Person.class, 1L );
72+
assertThat( entity.getVersion() ).isEqualTo( 1L );
73+
} );
74+
}
75+
76+
@Test
77+
public void testForceIncrementOnLock(SessionFactoryScope scope) {
78+
scope.inTransaction( session -> {
79+
Person entity = session.find( Person.class, 1L );
80+
assertThat( entity.getVersion() ).isEqualTo( 0L );
81+
session.lock( entity, LockMode.PESSIMISTIC_FORCE_INCREMENT );
82+
assertThat( entity.getVersion() ).isEqualTo( 1L );
83+
} );
84+
// in a different transaction
85+
scope.inTransaction( session -> {
86+
Person entity = session.find( Person.class, 1L );
87+
assertThat( entity.getVersion() ).isEqualTo( 1L );
88+
} );
89+
}
90+
91+
@Entity(name = "Person")
92+
@Cacheable
93+
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
94+
public static class Person {
95+
96+
@Id
97+
private Long id;
98+
@Version
99+
private Long version;
100+
private String name;
101+
102+
public Person() {
103+
}
104+
105+
public Person(final long id, final String name) {
106+
setId( id );
107+
setName( name );
108+
}
109+
110+
public Long getId() {
111+
return id;
112+
}
113+
114+
public void setId(final Long id) {
115+
this.id = id;
116+
}
117+
118+
public Long getVersion() {
119+
return version;
120+
}
121+
122+
public void setVersion(Long version) {
123+
this.version = version;
124+
}
125+
126+
public String getName() {
127+
return name;
128+
}
129+
130+
public void setName(final String name) {
131+
this.name = name;
132+
}
133+
134+
}
135+
}

0 commit comments

Comments
 (0)