|
5 | 5 | package org.hibernate.orm.test.mapping.naturalid; |
6 | 6 |
|
7 | 7 | import jakarta.persistence.Entity; |
| 8 | +import jakarta.persistence.GeneratedValue; |
8 | 9 | import jakarta.persistence.Id; |
| 10 | +import jakarta.persistence.OptimisticLockException; |
9 | 11 | import jakarta.persistence.Table; |
| 12 | +import org.hibernate.StaleObjectStateException; |
10 | 13 | import org.hibernate.annotations.NaturalId; |
11 | 14 | import org.hibernate.annotations.NaturalIdCache; |
12 | 15 | import org.hibernate.cache.internal.NaturalIdCacheKey; |
|
27 | 30 | import org.junit.jupiter.api.Test; |
28 | 31 |
|
29 | 32 | import static org.assertj.core.api.Assertions.assertThat; |
| 33 | +import static org.assertj.core.api.Assertions.fail; |
30 | 34 | import static org.hibernate.KeyType.NATURAL; |
31 | 35 |
|
32 | 36 | /// Tests for [org.hibernate.engine.spi.NaturalIdResolutions] |
33 | 37 | /// |
34 | 38 | /// @author Steve Ebersole |
35 | 39 | @SuppressWarnings("JUnitMalformedDeclaration") |
36 | 40 | @ServiceRegistry(settings = @Setting( name = CacheSettings.USE_SECOND_LEVEL_CACHE, value = "true" ) ) |
37 | | -@DomainModel(annotatedClasses = {XRefTests.Book.class,XRefTests.Bookmark.class,XRefTests.Pen.class}) |
| 41 | +@DomainModel(annotatedClasses = { |
| 42 | + XRefTests.Another.class, |
| 43 | + XRefTests.Book.class, |
| 44 | + XRefTests.Bookmark.class, |
| 45 | + XRefTests.Pen.class |
| 46 | +}) |
38 | 47 | @SessionFactory(useCollectingStatementInspector = true) |
39 | 48 | public class XRefTests { |
40 | 49 | public static final String BOOK_ISBN = "123-4567-890"; |
@@ -198,6 +207,31 @@ private void verifyCacheResolution(Class<?> entityType, String naturalId, int id |
198 | 207 | assertThat( resolution.getValue() ).isEqualTo( id ); |
199 | 208 | } |
200 | 209 |
|
| 210 | + @Test |
| 211 | + void testDeletionInOtherSession(SessionFactoryScope factoryScope) { |
| 212 | + var created = factoryScope.fromTransaction( (session) -> { |
| 213 | + var other = new Another( "something" ); |
| 214 | + session.persist( other ); |
| 215 | + return other; |
| 216 | + } ); |
| 217 | + |
| 218 | + factoryScope.inTransaction( (session) -> { |
| 219 | + var b = session.getReference( Another.class, created.id ); |
| 220 | + session.remove( b ); |
| 221 | + } ); |
| 222 | + |
| 223 | + created.name = "something else"; |
| 224 | + try { |
| 225 | + factoryScope.inTransaction( (session) -> { |
| 226 | + session.merge( created ); |
| 227 | + } ); |
| 228 | + fail( "Expecting OptimisticLockException / StaleObjectStateException" ); |
| 229 | + } |
| 230 | + catch (OptimisticLockException expected) { |
| 231 | + assertThat( expected.getCause() ).isInstanceOf( StaleObjectStateException.class ); |
| 232 | + } |
| 233 | + } |
| 234 | + |
201 | 235 | @BeforeEach |
202 | 236 | void createTestData(SessionFactoryScope factoryScope) { |
203 | 237 | factoryScope.inTransaction( (session) -> { |
@@ -273,4 +307,21 @@ public Pen(Integer id, String manufacturer, String sku) { |
273 | 307 | this.sku = sku; |
274 | 308 | } |
275 | 309 | } |
| 310 | + |
| 311 | + @Entity(name="Another") |
| 312 | + @Table(name="others") |
| 313 | + public static class Another { |
| 314 | + @Id |
| 315 | + @GeneratedValue |
| 316 | + private Integer id; |
| 317 | + @NaturalId |
| 318 | + private String name; |
| 319 | + |
| 320 | + public Another() { |
| 321 | + } |
| 322 | + |
| 323 | + public Another(String name) { |
| 324 | + this.name = name; |
| 325 | + } |
| 326 | + } |
276 | 327 | } |
0 commit comments