18
18
import static org .assertj .core .api .Assertions .*;
19
19
20
20
import jakarta .persistence .EntityManager ;
21
+ import jakarta .persistence .OptimisticLockException ;
21
22
import jakarta .persistence .PersistenceContext ;
22
23
23
24
import java .util .Arrays ;
24
25
import java .util .Iterator ;
25
26
import java .util .List ;
27
+ import java .util .Map ;
28
+
29
+ import javax .sql .DataSource ;
26
30
27
31
import org .jetbrains .annotations .NotNull ;
28
32
import org .junit .jupiter .api .BeforeEach ;
29
33
import org .junit .jupiter .api .Test ;
30
34
import org .junit .jupiter .api .extension .ExtendWith ;
35
+ import org .springframework .beans .factory .annotation .Autowired ;
31
36
import org .springframework .data .jpa .domain .sample .PersistableWithIdClass ;
32
37
import org .springframework .data .jpa .domain .sample .PersistableWithIdClassPK ;
33
38
import org .springframework .data .jpa .domain .sample .SampleEntity ;
34
39
import org .springframework .data .jpa .domain .sample .SampleEntityPK ;
40
+ import org .springframework .data .jpa .domain .sample .VersionedUser ;
35
41
import org .springframework .data .jpa .repository .JpaRepository ;
36
42
import org .springframework .data .repository .CrudRepository ;
43
+ import org .springframework .jdbc .core .namedparam .NamedParameterJdbcOperations ;
44
+ import org .springframework .jdbc .core .namedparam .NamedParameterJdbcTemplate ;
37
45
import org .springframework .test .context .ContextConfiguration ;
38
46
import org .springframework .test .context .junit .jupiter .SpringExtension ;
39
47
import org .springframework .transaction .annotation .Transactional ;
46
54
* @author Jens Schauder
47
55
* @author Greg Turnquist
48
56
* @author Krzysztof Krason
57
+ * @author Yanming Zhou
49
58
*/
50
59
@ ExtendWith (SpringExtension .class )
51
60
@ ContextConfiguration ({ "classpath:infrastructure.xml" })
52
61
@ Transactional
53
62
class JpaRepositoryTests {
54
63
64
+ @ Autowired DataSource dataSource ;
65
+
55
66
@ PersistenceContext EntityManager em ;
56
67
57
68
private JpaRepository <SampleEntity , SampleEntityPK > repository ;
58
69
private CrudRepository <PersistableWithIdClass , PersistableWithIdClassPK > idClassRepository ;
70
+ private JpaRepository <VersionedUser , Long > versionedUserRepository ;
71
+ private NamedParameterJdbcOperations jdbcOperations ;
59
72
60
73
@ BeforeEach
61
74
void setUp () {
62
75
repository = new JpaRepositoryFactory (em ).getRepository (SampleEntityRepository .class );
63
76
idClassRepository = new JpaRepositoryFactory (em ).getRepository (SampleWithIdClassRepository .class );
77
+ versionedUserRepository = new JpaRepositoryFactory (em ).getRepository (VersionedUserRepository .class );
78
+ jdbcOperations = new NamedParameterJdbcTemplate (dataSource );
64
79
}
65
80
66
81
@ Test
@@ -162,6 +177,48 @@ public Iterator<SampleEntityPK> iterator() {
162
177
assertThat (repository .findAll ()).containsExactly (two );
163
178
}
164
179
180
+ @ Test
181
+ void deleteDirtyDetachedVersionedEntityShouldRaiseOptimisticLockException () {
182
+
183
+ VersionedUser entity = new VersionedUser ();
184
+ entity .setName ("name" );
185
+ versionedUserRepository .save (entity );
186
+ versionedUserRepository .flush ();
187
+ em .detach (entity );
188
+
189
+ versionedUserRepository .findById (entity .getId ()).ifPresent (u -> {
190
+ u .setName ("new name" );
191
+ versionedUserRepository .flush ();
192
+ });
193
+
194
+ assertThatExceptionOfType (OptimisticLockException .class ).isThrownBy (() -> {
195
+ versionedUserRepository .delete (entity );
196
+ versionedUserRepository .flush ();
197
+ });
198
+
199
+ jdbcOperations .update ("delete from VersionedUser" , Map .of ());
200
+ }
201
+
202
+ @ Test
203
+ void deleteDirtyManagedVersionedEntityShouldRaiseOptimisticLockException () {
204
+
205
+ VersionedUser entity = new VersionedUser ();
206
+ entity .setName ("name" );
207
+ versionedUserRepository .save (entity );
208
+ versionedUserRepository .flush ();
209
+
210
+
211
+ assertThat (jdbcOperations .update ("update VersionedUser set version=version+1 where id=:id" ,
212
+ Map .of ("id" , entity .getId ()))).isEqualTo (1 );
213
+
214
+ assertThatExceptionOfType (OptimisticLockException .class ).isThrownBy (() -> {
215
+ versionedUserRepository .delete (entity );
216
+ versionedUserRepository .flush ();
217
+ });
218
+
219
+ jdbcOperations .update ("delete from VersionedUser" , Map .of ());
220
+ }
221
+
165
222
private interface SampleEntityRepository extends JpaRepository <SampleEntity , SampleEntityPK > {
166
223
167
224
}
@@ -170,4 +227,8 @@ private interface SampleWithIdClassRepository
170
227
extends CrudRepository <PersistableWithIdClass , PersistableWithIdClassPK > {
171
228
172
229
}
230
+
231
+ private interface VersionedUserRepository extends JpaRepository <VersionedUser , Long > {
232
+
233
+ }
173
234
}
0 commit comments