1010import java .util .Objects ;
1111
1212import org .hibernate .query .criteria .HibernateCriteriaBuilder ;
13+ import org .hibernate .query .criteria .JpaCriteriaInsertSelect ;
14+ import org .hibernate .query .criteria .JpaCriteriaInsertValues ;
15+ import org .hibernate .query .criteria .JpaCriteriaQuery ;
16+ import org .hibernate .query .criteria .JpaRoot ;
1317import org .hibernate .reactive .mutiny .Mutiny ;
1418import org .hibernate .reactive .stage .Stage ;
1519
2125import jakarta .persistence .Entity ;
2226import jakarta .persistence .Id ;
2327import jakarta .persistence .Table ;
28+ import jakarta .persistence .Tuple ;
2429import jakarta .persistence .criteria .CriteriaBuilder ;
2530import jakarta .persistence .criteria .CriteriaDelete ;
2631import jakarta .persistence .criteria .CriteriaUpdate ;
3136
3237@ Timeout (value = 10 , timeUnit = MINUTES )
3338public class CriteriaMutationQueryTest extends BaseReactiveTest {
34- Flour spelt = new Flour ( 1 , "Spelt" , "An ancient grain, is a hexaploid species of wheat." , "Wheat flour" );
39+ private static final Integer SPELT_ID = 1 ;
40+ private static final String SPELT_NAME = "Spelt" ;
41+ private static final String SPELT_TYPE = "Wheat flour" ;
42+ Flour spelt = new Flour ( SPELT_ID , SPELT_NAME , "An ancient grain, is a hexaploid species of wheat." , SPELT_TYPE );
3543 Flour rye = new Flour ( 2 , "Rye" , "Used to bake the traditional sourdough breads of Germany." , "Wheat flour" );
3644 Flour almond = new Flour ( 3 , "Almond" , "made from ground almonds." , "Gluten free" );
3745
@@ -102,6 +110,92 @@ public void testMutinyDeleteCriteriaQuery(VertxTestContext context) {
102110 );
103111 }
104112
113+ @ Test
114+ public void testStageInsertCriteriaQuery (VertxTestContext context ) {
115+ final int id = 4 ;
116+ final String flourName = "Rye" ;
117+ final String flourDescription = "Used to bake the traditional sourdough breads of Germany." ;
118+ final String flourType = "Wheat flour" ;
119+ test ( context , getSessionFactory ()
120+ .withTransaction ( s -> s
121+ .createMutationQuery ( insertCriteria ( getCriteriaBuilder ( s ), id , flourName , flourDescription , flourType ) )
122+ .executeUpdate ()
123+ )
124+ .thenAccept ( resultCount -> assertThat ( resultCount ).isEqualTo ( 1 ) )
125+ .thenCompose ( v -> getSessionFactory ()
126+ .withTransaction ( s -> s .find ( Flour .class , id ) ) )
127+ .thenAccept ( result -> {
128+ assertThat ( result ).isNotNull ();
129+ assertThat ( result .name ).isEqualTo ( flourName );
130+ assertThat ( result .description ).isEqualTo ( flourDescription );
131+ assertThat ( result .type ).isEqualTo ( flourType );
132+ } )
133+ );
134+ }
135+
136+ @ Test
137+ public void testMutinyInsertCriteriaQuery (VertxTestContext context ) {
138+ final int id = 4 ;
139+ final String flourName = "Almond" ;
140+ final String flourDescription = "made from ground almonds." ;
141+ final String flourType = "Gluten free" ;
142+ test ( context , getMutinySessionFactory ()
143+ .withTransaction ( s -> s
144+ .createMutationQuery ( insertCriteria ( getCriteriaBuilder ( s ), id , flourName , flourDescription , flourType ) )
145+ .executeUpdate ()
146+ )
147+ .invoke ( resultCount -> assertThat ( resultCount ).isEqualTo ( 1 ) )
148+ .chain ( v -> getMutinySessionFactory ()
149+ .withTransaction ( s -> s .find ( Flour .class , id ) ) )
150+ .invoke ( result -> {
151+ assertThat ( result ).isNotNull ();
152+ assertThat ( result .name ).isEqualTo ( flourName );
153+ assertThat ( result .description ).isEqualTo ( flourDescription );
154+ assertThat ( result .type ).isEqualTo ( flourType );
155+ } )
156+ );
157+ }
158+
159+ @ Test
160+ public void testStageInsertSelectCriteriaQuery (VertxTestContext context ) {
161+ final int idOfTheNewFlour = 4 ;
162+ test ( context , getSessionFactory ()
163+ .withTransaction ( s -> s
164+ .createMutationQuery ( insertSelectCriteria ( getCriteriaBuilder ( s ), idOfTheNewFlour ) )
165+ .executeUpdate ()
166+ )
167+ .thenAccept ( resultCount -> assertThat ( resultCount ).isEqualTo ( 1 ) )
168+ .thenCompose ( v -> getSessionFactory ()
169+ .withTransaction ( s -> s .find ( Flour .class , idOfTheNewFlour ) ) )
170+ .thenAccept ( result -> {
171+ assertThat ( result ).isNotNull ();
172+ assertThat ( result .name ).isEqualTo ( SPELT_NAME );
173+ assertThat ( result .description ).isNull ();
174+ assertThat ( result .type ).isEqualTo ( SPELT_TYPE );
175+ } )
176+ );
177+ }
178+
179+ @ Test
180+ public void testMutinyInsertSelectCriteriaQuery (VertxTestContext context ) {
181+ final int idOfTheNewFlour = 4 ;
182+ test ( context , getMutinySessionFactory ()
183+ .withTransaction ( s -> s
184+ .createMutationQuery ( insertSelectCriteria ( getCriteriaBuilder ( s ), idOfTheNewFlour ) )
185+ .executeUpdate ()
186+ )
187+ .invoke ( resultCount -> assertThat ( resultCount ).isEqualTo ( 1 ) )
188+ .chain ( v -> getMutinySessionFactory ()
189+ .withTransaction ( s -> s .find ( Flour .class , idOfTheNewFlour ) ) )
190+ .invoke ( result -> {
191+ assertThat ( result ).isNotNull ();
192+ assertThat ( result .name ).isEqualTo ( SPELT_NAME );
193+ assertThat ( result .description ).isNull ();
194+ assertThat ( result .type ).isEqualTo ( SPELT_TYPE );
195+ } )
196+ );
197+ }
198+
105199 private CriteriaUpdate <Flour > criteriaUpdate (CriteriaBuilder cb , String updatedDescription , Flour rye ) {
106200 CriteriaUpdate <Flour > criteriaUpdate = cb .createCriteriaUpdate ( Flour .class );
107201 Root <Flour > from = criteriaUpdate .from ( Flour .class );
@@ -117,6 +211,35 @@ private CriteriaDelete<Flour> criteriaUpdate(CriteriaBuilder criteriaBuilder) {
117211 return criteriaDelete ;
118212 }
119213
214+ private static JpaCriteriaInsertValues <Flour > insertCriteria (HibernateCriteriaBuilder cb , int id , String name , String description , String type ) {
215+ JpaCriteriaInsertValues <Flour > insert = cb .createCriteriaInsertValues ( Flour .class );
216+ JpaRoot <Flour > flour = insert .getTarget ();
217+ insert .setInsertionTargetPaths ( flour .get ( "id" ), flour .get ( "name" ), flour .get ( "description" ), flour .get ( "type" ) );
218+ insert .values ( cb .values ( cb .value ( id ), cb .value ( name ), cb .value ( description ), cb .value ( type ) ) );
219+ return insert ;
220+ }
221+
222+ private static JpaCriteriaInsertSelect <Flour > insertSelectCriteria (
223+ HibernateCriteriaBuilder cb ,
224+ int idOfTheNewFlour ) {
225+ /*
226+ The query executes and insert of Flour with id equals to 2 a name and type
227+ selected from the existing spelt flour saved in the db
228+ */
229+ JpaCriteriaInsertSelect <Flour > insertSelect = cb .createCriteriaInsertSelect ( Flour .class );
230+ // columns to insert
231+ JpaRoot <Flour > flour = insertSelect .getTarget ();
232+ insertSelect .setInsertionTargetPaths ( flour .get ( "id" ), flour .get ( "name" ), flour .get ( "type" ) );
233+ // select query
234+ JpaCriteriaQuery <Tuple > select = cb .createQuery ( Tuple .class );
235+ JpaRoot <Flour > root = select .from ( Flour .class );
236+ select .multiselect ( cb .literal ( idOfTheNewFlour ), root .get ( "name" ), root .get ( "type" ) );
237+ select .where ( cb .equal ( root .get ( "id" ), SPELT_ID ) );
238+
239+ insertSelect .select ( select );
240+ return insertSelect ;
241+ }
242+
120243 private static HibernateCriteriaBuilder getCriteriaBuilder (Stage .Session session ) {
121244 return session .getFactory ().getCriteriaBuilder ();
122245 }
0 commit comments