|
8 | 8 | import org.hibernate.metamodel.model.domain.EntityDomainType;
|
9 | 9 | import org.hibernate.metamodel.model.domain.internal.MappingMetamodelImpl;
|
10 | 10 | import org.hibernate.query.Order;
|
| 11 | +import org.hibernate.query.restriction.Restriction; |
| 12 | +import org.hibernate.query.specification.MutationSpecification; |
11 | 13 | import org.hibernate.query.specification.SelectionSpecification;
|
12 | 14 |
|
13 | 15 | import org.junit.jupiter.api.BeforeEach;
|
| 16 | +import org.junit.jupiter.api.Test; |
14 | 17 | import org.junit.jupiter.params.ParameterizedTest;
|
15 | 18 | import org.junit.jupiter.params.provider.Arguments;
|
16 | 19 | import org.junit.jupiter.params.provider.MethodSource;
|
|
20 | 23 | import jakarta.persistence.Entity;
|
21 | 24 | import jakarta.persistence.Id;
|
22 | 25 | import jakarta.persistence.Table;
|
| 26 | +import jakarta.persistence.TypedQueryReference; |
23 | 27 | import jakarta.persistence.metamodel.SingularAttribute;
|
24 | 28 | import java.util.Collection;
|
25 | 29 | import java.util.List;
|
|
36 | 40 | * Test for queries created using {@link SelectionSpecification}.
|
37 | 41 | */
|
38 | 42 | @Timeout(value = 10, timeUnit = MINUTES)
|
39 |
| -public class SelectionSpecificationTest extends BaseReactiveTest { |
| 43 | +public class QuerySpecificationTest extends BaseReactiveTest { |
40 | 44 | static final Book hibBook = new Book( 1L, "Hibernate in Action" );
|
41 | 45 | static final Book jpBook = new Book( 3L, "Java Persistence with Hibernate" );
|
42 | 46 | static final Book animalFarmBook = new Book( 2L, "Animal Farm" );
|
@@ -65,27 +69,6 @@ static Stream<Arguments> singleColumnOrderExpectation() {
|
65 | 69 | );
|
66 | 70 | }
|
67 | 71 |
|
68 |
| - static Stream<Arguments> multipleColumnOrderExpectation() { |
69 |
| - return Stream.of( |
70 |
| - arguments( |
71 |
| - List.of( asc( Book.class, "title" ), asc( Book.class, "isbn" ) ), |
72 |
| - List.of( animalFarmBook, animalFarmBook2, hibBook, jpBook ) |
73 |
| - ), |
74 |
| - arguments( |
75 |
| - List.of( asc( Book.class, "title" ), desc( Book.class, "isbn" ) ), |
76 |
| - List.of( animalFarmBook2, animalFarmBook, hibBook, jpBook ) |
77 |
| - ), |
78 |
| - arguments( |
79 |
| - List.of( desc( Book.class, "isbn" ), asc( Book.class, "title" ) ), |
80 |
| - List.of( animalFarmBook2, jpBook, animalFarmBook, hibBook ) |
81 |
| - ), |
82 |
| - arguments( |
83 |
| - List.of( desc( Book.class, "isbn" ), desc( Book.class, "title" ) ), |
84 |
| - List.of( animalFarmBook2, jpBook, animalFarmBook, hibBook ) |
85 |
| - ) |
86 |
| - ); |
87 |
| - } |
88 |
| - |
89 | 72 | @ParameterizedTest
|
90 | 73 | @MethodSource("singleColumnOrderExpectation")
|
91 | 74 | public void singleColumnOrderWithStage(Order<Book> order, List<Book> expectedList, VertxTestContext context) {
|
@@ -236,6 +219,27 @@ public void multipleColumnsOrderWithStage(List<Order<Book>> orders, List<Book> e
|
236 | 219 | );
|
237 | 220 | }
|
238 | 221 |
|
| 222 | + static Stream<Arguments> multipleColumnOrderExpectation() { |
| 223 | + return Stream.of( |
| 224 | + arguments( |
| 225 | + List.of( asc( Book.class, "title" ), asc( Book.class, "isbn" ) ), |
| 226 | + List.of( animalFarmBook, animalFarmBook2, hibBook, jpBook ) |
| 227 | + ), |
| 228 | + arguments( |
| 229 | + List.of( asc( Book.class, "title" ), desc( Book.class, "isbn" ) ), |
| 230 | + List.of( animalFarmBook2, animalFarmBook, hibBook, jpBook ) |
| 231 | + ), |
| 232 | + arguments( |
| 233 | + List.of( desc( Book.class, "isbn" ), asc( Book.class, "title" ) ), |
| 234 | + List.of( animalFarmBook2, jpBook, animalFarmBook, hibBook ) |
| 235 | + ), |
| 236 | + arguments( |
| 237 | + List.of( desc( Book.class, "isbn" ), desc( Book.class, "title" ) ), |
| 238 | + List.of( animalFarmBook2, jpBook, animalFarmBook, hibBook ) |
| 239 | + ) |
| 240 | + ); |
| 241 | + } |
| 242 | + |
239 | 243 | @ParameterizedTest
|
240 | 244 | @MethodSource("multipleColumnOrderExpectation")
|
241 | 245 | public void multipleColumnsOrderWithStageStateless(List<Order<Book>> orders, List<Book> expectedList, VertxTestContext context) {
|
@@ -290,6 +294,86 @@ public void multipleColumnsOrderWithMutinyStateless(List<Order<Book>> orders, Li
|
290 | 294 | );
|
291 | 295 | }
|
292 | 296 |
|
| 297 | + @Test |
| 298 | + public void mutationSpecificationWithStage(VertxTestContext context) { |
| 299 | + SingularAttribute<Book, String> title = (SingularAttribute<Book, String>) attribute( "title" ); |
| 300 | + TypedQueryReference<Void> deleteAnimalFarm = MutationSpecification |
| 301 | + .create( Book.class, "delete Book" ) |
| 302 | + .restrict( Restriction.equalIgnoringCase( title, animalFarmBook.title ) ) |
| 303 | + .reference(); |
| 304 | + |
| 305 | + test( context, getSessionFactory() |
| 306 | + .withTransaction( session -> session.persist( animalFarmBook2 ) ) |
| 307 | + .thenCompose( v -> getSessionFactory().withTransaction( session -> session |
| 308 | + .createQuery( deleteAnimalFarm ) |
| 309 | + .executeUpdate() ) ) |
| 310 | + .thenAccept( deleted -> assertThat( deleted ).isEqualTo( 2 ) ) |
| 311 | + .thenCompose( v -> getSessionFactory().withSession( session -> session |
| 312 | + .createQuery( "from Book", Book.class ).getResultList() ) ) |
| 313 | + .thenAccept( list -> assertThat( list ).containsExactlyInAnyOrder( hibBook, jpBook ) ) |
| 314 | + ); |
| 315 | + } |
| 316 | + |
| 317 | + @Test |
| 318 | + public void mutationSpecificationWithStageStateless(VertxTestContext context) { |
| 319 | + SingularAttribute<Book, String> title = (SingularAttribute<Book, String>) attribute( "title" ); |
| 320 | + TypedQueryReference<Void> deleteAnimalFarm = MutationSpecification |
| 321 | + .create( Book.class, "delete Book" ) |
| 322 | + .restrict( Restriction.equalIgnoringCase( title, animalFarmBook.title ) ) |
| 323 | + .reference(); |
| 324 | + |
| 325 | + test( context, getSessionFactory() |
| 326 | + .withTransaction( session -> session.persist( animalFarmBook2 ) ) |
| 327 | + .thenCompose( v -> getSessionFactory().withStatelessTransaction( session -> session |
| 328 | + .createQuery( deleteAnimalFarm ) |
| 329 | + .executeUpdate() ) ) |
| 330 | + .thenAccept( deleted -> assertThat( deleted ).isEqualTo( 2 ) ) |
| 331 | + .thenCompose( v -> getSessionFactory().withSession( session -> session |
| 332 | + .createQuery( "from Book", Book.class ).getResultList() ) ) |
| 333 | + .thenAccept( list -> assertThat( list ).containsExactlyInAnyOrder( hibBook, jpBook ) ) |
| 334 | + ); |
| 335 | + } |
| 336 | + |
| 337 | + @Test |
| 338 | + public void mutationSpecificationWithMutiny(VertxTestContext context) { |
| 339 | + SingularAttribute<Book, String> title = (SingularAttribute<Book, String>) attribute( "title" ); |
| 340 | + TypedQueryReference<Void> deleteAnimalFarm = MutationSpecification |
| 341 | + .create( Book.class, "delete Book" ) |
| 342 | + .restrict( Restriction.equalIgnoringCase( title, animalFarmBook.title ) ) |
| 343 | + .reference(); |
| 344 | + |
| 345 | + test( context, getMutinySessionFactory() |
| 346 | + .withTransaction( session -> session.persist( animalFarmBook2 ) ) |
| 347 | + .chain( v -> getMutinySessionFactory().withTransaction( session -> session |
| 348 | + .createQuery( deleteAnimalFarm ) |
| 349 | + .executeUpdate() ) ) |
| 350 | + .invoke( deleted -> assertThat( deleted ).isEqualTo( 2 ) ) |
| 351 | + .chain( () -> getMutinySessionFactory().withSession( session -> session |
| 352 | + .createQuery( "from Book", Book.class ).getResultList() ) ) |
| 353 | + .invoke( list -> assertThat( list ).containsExactlyInAnyOrder( hibBook, jpBook ) ) |
| 354 | + ); |
| 355 | + } |
| 356 | + |
| 357 | + @Test |
| 358 | + public void mutationSpecificationWithMutinyStateless(VertxTestContext context) { |
| 359 | + SingularAttribute<Book, String> title = (SingularAttribute<Book, String>) attribute( "title" ); |
| 360 | + TypedQueryReference<Void> deleteAnimalFarm = MutationSpecification |
| 361 | + .create( Book.class, "delete Book" ) |
| 362 | + .restrict( Restriction.equalIgnoringCase( title, animalFarmBook.title ) ) |
| 363 | + .reference(); |
| 364 | + |
| 365 | + test( context, getMutinySessionFactory() |
| 366 | + .withStatelessTransaction( session -> session.insert( animalFarmBook2 ) ) |
| 367 | + .chain( v -> getMutinySessionFactory().withStatelessTransaction( session -> session |
| 368 | + .createQuery( deleteAnimalFarm ) |
| 369 | + .executeUpdate() ) ) |
| 370 | + .invoke( deleted -> assertThat( deleted ).isEqualTo( 2 ) ) |
| 371 | + .chain( () -> getMutinySessionFactory().withStatelessSession( session -> session |
| 372 | + .createQuery( "from Book", Book.class ).getResultList() ) ) |
| 373 | + .invoke( list -> assertThat( list ).containsExactlyInAnyOrder( hibBook, jpBook ) ) |
| 374 | + ); |
| 375 | + } |
| 376 | + |
293 | 377 | private SingularAttribute<? super Book, ?> attribute(String name) {
|
294 | 378 | MappingMetamodelImpl metamodel = (MappingMetamodelImpl) getSessionFactory().getMetamodel();
|
295 | 379 | EntityDomainType<Book> bookType = metamodel.getJpaMetamodel().findEntityType( Book.class );
|
|
0 commit comments