Skip to content

Commit 0fa0f9d

Browse files
committed
fix
1 parent 679b8ba commit 0fa0f9d

File tree

3 files changed

+116
-24
lines changed

3 files changed

+116
-24
lines changed

hibernate-reactive-core/src/main/java/org/hibernate/reactive/session/impl/ReactiveSessionImpl.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,11 @@ public <R> ReactiveQuery<R> createReactiveQuery(TypedQueryReference<R> typedQuer
370370
}
371371
if ( typedQueryReference instanceof MutationSpecificationImpl<?> specification ) {
372372
final CommonAbstractCriteria query = specification.buildCriteria( getCriteriaBuilder() );
373-
return new ReactiveQuerySqmImpl<>( (SqmStatement<R>) query, (Class<R>) specification.getResultType(), this );
373+
// Workaround for ORM
374+
Class<R> type = specification.getResultType() == Void.class
375+
? null
376+
: (Class<R>) specification.getResultType();
377+
return new ReactiveQuerySqmImpl<>( (SqmStatement<R>) query, type, this );
374378
}
375379
@SuppressWarnings("unchecked")
376380
// this cast is fine because of all our impls of TypedQueryReference return Class<R>

hibernate-reactive-core/src/main/java/org/hibernate/reactive/session/impl/ReactiveStatelessSessionImpl.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -805,7 +805,11 @@ public <R> ReactiveQuery<R> createReactiveQuery(TypedQueryReference<R> typedQuer
805805
}
806806
if ( typedQueryReference instanceof MutationSpecificationImpl<?> specification ) {
807807
final CommonAbstractCriteria query = specification.buildCriteria( getCriteriaBuilder() );
808-
return new ReactiveQuerySqmImpl<>( (SqmStatement<R>) query, (Class<R>) specification.getResultType(), this );
808+
// Workaround for ORM
809+
Class<R> type = (Class<R>) specification.getResultType() == Void.class
810+
? null
811+
: (Class<R>) specification.getResultType();
812+
return new ReactiveQuerySqmImpl<>( (SqmStatement<R>) query, type, this );
809813
}
810814
@SuppressWarnings("unchecked")
811815
// this cast is fine because of all our impls of TypedQueryReference return Class<R>

hibernate-reactive-core/src/test/java/org/hibernate/reactive/SelectionSpecificationTest.java renamed to hibernate-reactive-core/src/test/java/org/hibernate/reactive/QuerySpecificationTest.java

+106-22
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@
88
import org.hibernate.metamodel.model.domain.EntityDomainType;
99
import org.hibernate.metamodel.model.domain.internal.MappingMetamodelImpl;
1010
import org.hibernate.query.Order;
11+
import org.hibernate.query.restriction.Restriction;
12+
import org.hibernate.query.specification.MutationSpecification;
1113
import org.hibernate.query.specification.SelectionSpecification;
1214

1315
import org.junit.jupiter.api.BeforeEach;
16+
import org.junit.jupiter.api.Test;
1417
import org.junit.jupiter.params.ParameterizedTest;
1518
import org.junit.jupiter.params.provider.Arguments;
1619
import org.junit.jupiter.params.provider.MethodSource;
@@ -20,6 +23,7 @@
2023
import jakarta.persistence.Entity;
2124
import jakarta.persistence.Id;
2225
import jakarta.persistence.Table;
26+
import jakarta.persistence.TypedQueryReference;
2327
import jakarta.persistence.metamodel.SingularAttribute;
2428
import java.util.Collection;
2529
import java.util.List;
@@ -36,7 +40,7 @@
3640
* Test for queries created using {@link SelectionSpecification}.
3741
*/
3842
@Timeout(value = 10, timeUnit = MINUTES)
39-
public class SelectionSpecificationTest extends BaseReactiveTest {
43+
public class QuerySpecificationTest extends BaseReactiveTest {
4044
static final Book hibBook = new Book( 1L, "Hibernate in Action" );
4145
static final Book jpBook = new Book( 3L, "Java Persistence with Hibernate" );
4246
static final Book animalFarmBook = new Book( 2L, "Animal Farm" );
@@ -65,27 +69,6 @@ static Stream<Arguments> singleColumnOrderExpectation() {
6569
);
6670
}
6771

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-
8972
@ParameterizedTest
9073
@MethodSource("singleColumnOrderExpectation")
9174
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
236219
);
237220
}
238221

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+
239243
@ParameterizedTest
240244
@MethodSource("multipleColumnOrderExpectation")
241245
public void multipleColumnsOrderWithStageStateless(List<Order<Book>> orders, List<Book> expectedList, VertxTestContext context) {
@@ -290,6 +294,86 @@ public void multipleColumnsOrderWithMutinyStateless(List<Order<Book>> orders, Li
290294
);
291295
}
292296

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+
293377
private SingularAttribute<? super Book, ?> attribute(String name) {
294378
MappingMetamodelImpl metamodel = (MappingMetamodelImpl) getSessionFactory().getMetamodel();
295379
EntityDomainType<Book> bookType = metamodel.getJpaMetamodel().findEntityType( Book.class );

0 commit comments

Comments
 (0)