Skip to content

Commit eb4df2d

Browse files
wanderer2097jrenaat
authored andcommitted
HHH-18992 adding tests
1 parent 05677eb commit eb4df2d

File tree

1 file changed

+235
-0
lines changed

1 file changed

+235
-0
lines changed
Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
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.loading.multiLoad;
6+
7+
import static org.junit.Assert.assertEquals;
8+
import static org.junit.Assert.assertNotNull;
9+
import static org.junit.Assert.assertTrue;
10+
11+
import java.util.List;
12+
import java.util.stream.Collectors;
13+
14+
import org.hibernate.LockMode;
15+
import org.hibernate.LockOptions;
16+
import org.hibernate.cfg.AvailableSettings;
17+
import org.hibernate.orm.test.cache.Company;
18+
import org.hibernate.orm.test.cache.User;
19+
import org.hibernate.testing.orm.domain.gambit.EntityWithAggregateId;
20+
import org.hibernate.testing.orm.junit.DomainModel;
21+
import org.hibernate.testing.orm.junit.JiraKey;
22+
import org.hibernate.testing.orm.junit.ServiceRegistry;
23+
import org.hibernate.testing.orm.junit.SessionFactory;
24+
import org.hibernate.testing.orm.junit.SessionFactoryScope;
25+
import org.hibernate.testing.orm.junit.Setting;
26+
import org.junit.jupiter.api.BeforeEach;
27+
import org.junit.jupiter.api.Test;
28+
29+
import jakarta.persistence.Basic;
30+
import jakarta.persistence.Entity;
31+
import jakarta.persistence.Id;
32+
33+
34+
@DomainModel(
35+
annotatedClasses = {
36+
MultiLoadLockingTest.Customer.class,
37+
EntityWithAggregateId.class,
38+
User.class,
39+
Company.class
40+
}
41+
)
42+
@SessionFactory
43+
@ServiceRegistry(
44+
settings = {
45+
@Setting(name = AvailableSettings.USE_QUERY_CACHE, value = "true"),
46+
@Setting(name = AvailableSettings.USE_SECOND_LEVEL_CACHE, value = "true")
47+
}
48+
)
49+
@JiraKey(value = "HHH-18992")
50+
public class MultiLoadLockingTest {
51+
52+
private List<Customer> customerList = List.of(
53+
new Customer(1L, "Customer A"),
54+
new Customer(2L, "Customer B"),
55+
new Customer(3L, "Customer C"),
56+
new Customer(4L, "Customer D"),
57+
new Customer(5L, "Customer E")
58+
);
59+
60+
private List<Long> customerIds = customerList
61+
.stream()
62+
.map(Customer::getId)
63+
.collect(Collectors.toList());
64+
65+
private List<EntityWithAggregateId> entityWithAggregateIdList = List.of(
66+
new EntityWithAggregateId( new EntityWithAggregateId.Key( "1", "1" ), "Entity A" ),
67+
new EntityWithAggregateId( new EntityWithAggregateId.Key( "2", "2" ), "Entity B" ),
68+
new EntityWithAggregateId( new EntityWithAggregateId.Key( "3", "3" ), "Entity C" ),
69+
new EntityWithAggregateId( new EntityWithAggregateId.Key( "4", "4" ), "Entity D" ),
70+
new EntityWithAggregateId( new EntityWithAggregateId.Key( "5", "5" ), "Entity E" )
71+
);
72+
73+
private List<EntityWithAggregateId.Key> entityWithAggregateIdKeys = entityWithAggregateIdList
74+
.stream()
75+
.map(EntityWithAggregateId::getKey)
76+
.collect(Collectors.toList());
77+
78+
public List<User> userList = List.of(
79+
new User(1, null),
80+
new User(2, null),
81+
new User(3, null),
82+
new User(4, null),
83+
new User(5, null)
84+
);
85+
86+
private List<Integer> userIds = userList
87+
.stream()
88+
.map(User::getId)
89+
.collect(Collectors.toList());
90+
91+
92+
@BeforeEach
93+
public void prepareTestDataAndClearL2C(SessionFactoryScope scope) {
94+
scope.inTransaction(session -> {
95+
customerList.forEach( session::persist );
96+
entityWithAggregateIdList.forEach( session::persist );
97+
userList.forEach( session::persist );
98+
});
99+
scope.getSessionFactory().getCache().evictAll();
100+
}
101+
102+
// (1) simple Id entity w/ pessimistic read lock
103+
104+
@Test
105+
void testMultiLoadSimpleIdEntityPessimisticReadLock(SessionFactoryScope scope) {
106+
scope.inTransaction( session -> {
107+
List<Customer> customersLoaded = session.byMultipleIds(Customer.class)
108+
.with(new LockOptions(LockMode.PESSIMISTIC_READ))
109+
.multiLoad(customerIds);
110+
assertNotNull(customersLoaded);
111+
assertEquals(customerList.size(), customersLoaded.size());
112+
customersLoaded.forEach(customer -> {
113+
assertEquals(LockMode.PESSIMISTIC_READ, session.getCurrentLockMode(customer));
114+
});
115+
} );
116+
}
117+
118+
// (2) composite Id entity w/ pessimistic read lock (one of the entities already in L1C)
119+
120+
@Test
121+
void testMultiLoadCompositeIdEntityPessimisticReadLockAlreadyInSession(
122+
SessionFactoryScope scope) {
123+
scope.inTransaction( session -> {
124+
EntityWithAggregateId entityInL1C = session
125+
.find(EntityWithAggregateId.class, entityWithAggregateIdList.get(0).getKey());
126+
assertNotNull(entityInL1C);
127+
List<EntityWithAggregateId> entitiesLoaded = session.byMultipleIds(EntityWithAggregateId.class)
128+
.with(new LockOptions(LockMode.PESSIMISTIC_READ))
129+
.enableSessionCheck(true)
130+
.multiLoad(entityWithAggregateIdKeys);
131+
assertNotNull(entitiesLoaded);
132+
assertEquals(entityWithAggregateIdList.size(), entitiesLoaded.size());
133+
entitiesLoaded.forEach(entity -> {
134+
assertEquals(LockMode.PESSIMISTIC_READ, session.getCurrentLockMode(entity));
135+
});
136+
} );
137+
}
138+
139+
// (3) simple Id entity w/ pessimistic write lock (one in L1C & some in L2C)
140+
141+
@Test
142+
public void testMultiLoadSimpleIdEntityPessimisticWriteLockSomeInL1CAndSomeInL2C(
143+
SessionFactoryScope scope) {
144+
Integer userInL2CId = userIds.get(0);
145+
Integer userInL1CId = userIds.get(1);
146+
scope.inTransaction( session -> {
147+
User userInL2C = session.find(User.class, userInL2CId);
148+
assertNotNull(userInL2C);
149+
} );
150+
scope.inTransaction( session -> {
151+
assertTrue(session.getFactory().getCache().containsEntity(User.class, userInL2CId));
152+
User userInL1C = session.find(User.class, userInL1CId);
153+
assertNotNull(userInL1C);
154+
List<User> usersLoaded = session.byMultipleIds(User.class)
155+
.with(new LockOptions(LockMode.PESSIMISTIC_WRITE))
156+
.multiLoad(userIds);
157+
assertNotNull(usersLoaded);
158+
assertEquals(userList.size(), usersLoaded.size());
159+
usersLoaded.forEach(user -> {
160+
assertEquals(LockMode.PESSIMISTIC_WRITE, session.getCurrentLockMode(user));
161+
});
162+
} );
163+
}
164+
165+
166+
167+
// (4) simple Id entity w/ optimistic read lock
168+
169+
@Test
170+
void testMultiLoadSimpleIdEntityOptimisticReadLock(SessionFactoryScope scope) {
171+
scope.inTransaction( session -> {
172+
List<Customer> customersLoaded = session.byMultipleIds(Customer.class)
173+
.with(new LockOptions(LockMode.OPTIMISTIC))
174+
.multiLoad(customerIds);
175+
assertNotNull(customersLoaded);
176+
assertEquals(customerList.size(), customersLoaded.size());
177+
customersLoaded.forEach(customer -> {
178+
assertEquals(LockMode.OPTIMISTIC, session.getCurrentLockMode(customer));
179+
});
180+
} );
181+
}
182+
183+
184+
// (5) simple Id entity w/ optimistic force increment lock
185+
186+
@Test
187+
void testMultiLoadSimpleIdEntityOptimisticForceIncrementLock(SessionFactoryScope scope) {
188+
scope.inTransaction( session -> {
189+
List<Customer> customersLoaded = session.byMultipleIds(Customer.class)
190+
.with(new LockOptions(LockMode.OPTIMISTIC_FORCE_INCREMENT))
191+
.multiLoad(customerIds);
192+
assertNotNull(customersLoaded);
193+
assertEquals(customerList.size(), customersLoaded.size());
194+
customersLoaded.forEach(customer -> {
195+
assertEquals(LockMode.OPTIMISTIC_FORCE_INCREMENT, session.getCurrentLockMode(customer));
196+
});
197+
} );
198+
}
199+
200+
201+
202+
@Entity
203+
public static class Customer {
204+
205+
@Id
206+
private Long id;
207+
@Basic
208+
private String name;
209+
210+
protected Customer() {
211+
}
212+
213+
public Customer(Long id, String name) {
214+
this.id = id;
215+
this.name = name;
216+
}
217+
218+
public Long getId() {
219+
return id;
220+
}
221+
222+
public void setId(Long id) {
223+
this.id = id;
224+
}
225+
226+
public String getName() {
227+
return name;
228+
}
229+
230+
public void setName(String name) {
231+
this.name = name;
232+
}
233+
234+
}
235+
}

0 commit comments

Comments
 (0)