1
1
package io .quarkus .hibernate .reactive .panache .common .runtime ;
2
2
3
+ import static io .quarkus .hibernate .orm .runtime .PersistenceUnitUtil .DEFAULT_PERSISTENCE_UNIT_NAME ;
4
+
3
5
import java .util .ArrayList ;
6
+ import java .util .Arrays ;
4
7
import java .util .Collections ;
5
8
import java .util .List ;
6
9
import java .util .Map ;
7
10
import java .util .Map .Entry ;
11
+ import java .util .stream .Collectors ;
8
12
import java .util .stream .Stream ;
9
13
10
14
import jakarta .persistence .LockModeType ;
19
23
import io .smallrye .mutiny .Uni ;
20
24
21
25
public abstract class AbstractJpaOperations <PanacheQueryType > {
26
+ private static volatile Map <String , String > entityToPersistenceUnit = Collections .emptyMap ();
27
+
28
+ public static void setEntityToPersistenceUnit (Map <String , String > map ) {
29
+ entityToPersistenceUnit = Collections .unmodifiableMap (map );
30
+ }
22
31
23
32
// FIXME: make it configurable?
24
33
static final long TIMEOUT_MS = 5000 ;
@@ -34,7 +43,7 @@ protected abstract PanacheQueryType createPanacheQuery(Uni<Mutiny.Session> sessi
34
43
// Instance methods
35
44
36
45
public Uni <Void > persist (Object entity ) {
37
- return persist (getSession (), entity );
46
+ return persist (getSession (entity . getClass () ), entity );
38
47
}
39
48
40
49
public Uni <Void > persist (Uni <Mutiny .Session > sessionUni , Object entity ) {
@@ -67,20 +76,60 @@ public Uni<Void> persist(Stream<?> entities) {
67
76
}
68
77
69
78
public Uni <Void > persist (Object ... entities ) {
70
- return getSession ().chain (session -> session .persistAll (entities ));
79
+ Map <String , List <Object >> sessions = Arrays .stream (entities )
80
+ .collect (Collectors .groupingBy (e -> entityToPersistenceUnit .get (e .getClass ().getName ())));
81
+
82
+ List <Uni <Void >> results = new ArrayList <>();
83
+ for (Entry <String , List <Object >> entry : sessions .entrySet ()) {
84
+ results .add (getSession (entry .getKey ()).chain (session -> session .persistAll (entry .getValue ().toArray ())));
85
+ }
86
+
87
+ return Uni .combine ().all ().unis (results ).discardItems ();
71
88
}
72
89
73
90
public Uni <Void > delete (Object entity ) {
74
- return getSession ().chain (session -> session .remove (entity ));
91
+ return getSession (entity . getClass () ).chain (session -> session .remove (entity ));
75
92
}
76
93
77
94
public boolean isPersistent (Object entity ) {
78
- Mutiny .Session current = SessionOperations .getCurrentSession ();
79
- return current != null ? current .contains (entity ) : false ;
95
+ Session currentSession = getCurrentSession (entity .getClass ());
96
+ if (currentSession == null ) {
97
+ // No active session so object can't be persistent
98
+ return false ;
99
+ }
100
+
101
+ return currentSession .contains (entity );
102
+ }
103
+
104
+ public Session getCurrentSession (Class <?> entityClass ) {
105
+ String persistenceUnitName = entityToPersistenceUnit .get (entityClass .getName ());
106
+ return SessionOperations .getCurrentSession (persistenceUnitName );
80
107
}
81
108
109
+ /*
110
+ * Used by Panache repositories.
111
+ *
112
+ * This method flushes *all* persistence units.
113
+ * Ideally, it should flush only the session associated with the repository’s entity,
114
+ * but we don’t currently track the entity inside the repository.
115
+ *
116
+ * In Panache blocking, Quarkus injects the current EntityManager.
117
+ * In reactive mode, however, there is not yet an injectable Mutiny.Session
118
+ * (see https://github.com/quarkusio/quarkus/issues/47462).
119
+ */
82
120
public Uni <Void > flush () {
83
- return getSession ().chain (Session ::flush );
121
+ return allSessions ()
122
+ .chain (sessions -> {
123
+ List <Uni <Void >> flushes = sessions .stream ()
124
+ .map (Session ::flush )
125
+ .toList ();
126
+
127
+ return Uni .combine ().all ().unis (flushes ).discardItems ();
128
+ });
129
+ }
130
+
131
+ public Uni <Void > flush (Object entity ) {
132
+ return getSession (entity .getClass ()).chain (Session ::flush );
84
133
}
85
134
86
135
public int paramCount (Object [] params ) {
@@ -95,11 +144,11 @@ public int paramCount(Map<String, Object> params) {
95
144
// Queries
96
145
97
146
public Uni <?> findById (Class <?> entityClass , Object id ) {
98
- return getSession ().chain (session -> session .find (entityClass , id ));
147
+ return getSession (entityClass ).chain (session -> session .find (entityClass , id ));
99
148
}
100
149
101
150
public Uni <?> findById (Class <?> entityClass , Object id , LockModeType lockModeType ) {
102
- return getSession ()
151
+ return getSession (entityClass )
103
152
.chain (session -> session .find (entityClass , id , LockModeConverter .convertToLockMode (lockModeType )));
104
153
}
105
154
@@ -108,7 +157,7 @@ public PanacheQueryType find(Class<?> entityClass, String panacheQuery, Object..
108
157
}
109
158
110
159
public PanacheQueryType find (Class <?> entityClass , String panacheQuery , Sort sort , Object ... params ) {
111
- Uni <Mutiny .Session > session = getSession ();
160
+ Uni <Mutiny .Session > session = getSession (entityClass );
112
161
if (PanacheJpaUtil .isNamedQuery (panacheQuery )) {
113
162
String namedQuery = panacheQuery .substring (1 );
114
163
if (sort != null ) {
@@ -128,7 +177,7 @@ public PanacheQueryType find(Class<?> entityClass, String panacheQuery, Map<Stri
128
177
}
129
178
130
179
public PanacheQueryType find (Class <?> entityClass , String panacheQuery , Sort sort , Map <String , Object > params ) {
131
- Uni <Mutiny .Session > session = getSession ();
180
+ Uni <Mutiny .Session > session = getSession (entityClass );
132
181
if (PanacheJpaUtil .isNamedQuery (panacheQuery )) {
133
182
String namedQuery = panacheQuery .substring (1 );
134
183
if (sort != null ) {
@@ -177,13 +226,13 @@ public Uni<List<?>> list(Class<?> entityClass, String query, Sort sort, Paramete
177
226
178
227
public PanacheQueryType findAll (Class <?> entityClass ) {
179
228
String query = "FROM " + PanacheJpaUtil .getEntityName (entityClass );
180
- Uni <Mutiny .Session > session = getSession ();
229
+ Uni <Mutiny .Session > session = getSession (entityClass );
181
230
return createPanacheQuery (session , query , null , null , null );
182
231
}
183
232
184
233
public PanacheQueryType findAll (Class <?> entityClass , Sort sort ) {
185
234
String query = "FROM " + PanacheJpaUtil .getEntityName (entityClass );
186
- Uni <Mutiny .Session > session = getSession ();
235
+ Uni <Mutiny .Session > session = getSession (entityClass );
187
236
return createPanacheQuery (session , query , null , PanacheJpaUtil .toOrderBy (sort ), null );
188
237
}
189
238
@@ -196,7 +245,7 @@ public Uni<List<?>> listAll(Class<?> entityClass, Sort sort) {
196
245
}
197
246
198
247
public Uni <Long > count (Class <?> entityClass ) {
199
- return getSession ()
248
+ return getSession (entityClass )
200
249
.chain (session -> session
201
250
.createSelectionQuery ("FROM " + PanacheJpaUtil .getEntityName (entityClass ), entityClass )
202
251
.getResultCount ());
@@ -206,13 +255,13 @@ public Uni<Long> count(Class<?> entityClass) {
206
255
public Uni <Long > count (Class <?> entityClass , String panacheQuery , Object ... params ) {
207
256
208
257
if (PanacheJpaUtil .isNamedQuery (panacheQuery ))
209
- return (Uni ) getSession ().chain (session -> {
258
+ return (Uni ) getSession (entityClass ).chain (session -> {
210
259
String namedQueryName = panacheQuery .substring (1 );
211
260
NamedQueryUtil .checkNamedQuery (entityClass , namedQueryName );
212
261
return bindParameters (session .createNamedQuery (namedQueryName , Long .class ), params ).getSingleResult ();
213
262
});
214
263
215
- return getSession ().chain (session -> bindParameters (
264
+ return getSession (entityClass ).chain (session -> bindParameters (
216
265
session .createSelectionQuery (PanacheJpaUtil .createQueryForCount (entityClass , panacheQuery , paramCount (params )),
217
266
Object .class ),
218
267
params ).getResultCount ())
@@ -223,13 +272,13 @@ public Uni<Long> count(Class<?> entityClass, String panacheQuery, Object... para
223
272
public Uni <Long > count (Class <?> entityClass , String panacheQuery , Map <String , Object > params ) {
224
273
225
274
if (PanacheJpaUtil .isNamedQuery (panacheQuery ))
226
- return getSession ().chain (session -> {
275
+ return getSession (entityClass ).chain (session -> {
227
276
String namedQueryName = panacheQuery .substring (1 );
228
277
NamedQueryUtil .checkNamedQuery (entityClass , namedQueryName );
229
278
return bindParameters (session .createNamedQuery (namedQueryName , Long .class ), params ).getSingleResult ();
230
279
});
231
280
232
- return getSession ().chain (session -> bindParameters (
281
+ return getSession (entityClass ).chain (session -> bindParameters (
233
282
session .createSelectionQuery (PanacheJpaUtil .createQueryForCount (entityClass , panacheQuery , paramCount (params )),
234
283
Object .class ),
235
284
params ).getResultCount ())
@@ -258,7 +307,7 @@ public Uni<Boolean> exists(Class<?> entityClass, String query, Parameters params
258
307
}
259
308
260
309
public Uni <Long > deleteAll (Class <?> entityClass ) {
261
- return getSession ().chain (
310
+ return getSession (entityClass ).chain (
262
311
session -> session .createMutationQuery ("DELETE FROM " + PanacheJpaUtil .getEntityName (entityClass ))
263
312
.executeUpdate ()
264
313
.map (Integer ::longValue ));
@@ -272,20 +321,20 @@ public Uni<Boolean> deleteById(Class<?> entityClass, Object id) {
272
321
if (entity == null ) {
273
322
return Uni .createFrom ().item (false );
274
323
}
275
- return getSession ().chain (session -> session .remove (entity ).map (v -> true ));
324
+ return getSession (entityClass ).chain (session -> session .remove (entity ).map (v -> true ));
276
325
});
277
326
}
278
327
279
328
public Uni <Long > delete (Class <?> entityClass , String panacheQuery , Object ... params ) {
280
329
281
330
if (PanacheJpaUtil .isNamedQuery (panacheQuery ))
282
- return getSession ().chain (session -> {
331
+ return getSession (entityClass ).chain (session -> {
283
332
String namedQueryName = panacheQuery .substring (1 );
284
333
NamedQueryUtil .checkNamedQuery (entityClass , namedQueryName );
285
334
return bindParameters (session .createNamedQuery (namedQueryName ), params ).executeUpdate ().map (Integer ::longValue );
286
335
});
287
336
288
- return getSession ().chain (session -> bindParameters (
337
+ return getSession (entityClass ).chain (session -> bindParameters (
289
338
session .createMutationQuery (PanacheJpaUtil .createDeleteQuery (entityClass , panacheQuery , paramCount (params ))),
290
339
params )
291
340
.executeUpdate ().map (Integer ::longValue ))
@@ -296,13 +345,13 @@ public Uni<Long> delete(Class<?> entityClass, String panacheQuery, Object... par
296
345
public Uni <Long > delete (Class <?> entityClass , String panacheQuery , Map <String , Object > params ) {
297
346
298
347
if (PanacheJpaUtil .isNamedQuery (panacheQuery ))
299
- return getSession ().chain (session -> {
348
+ return getSession (entityClass ).chain (session -> {
300
349
String namedQueryName = panacheQuery .substring (1 );
301
350
NamedQueryUtil .checkNamedQuery (entityClass , namedQueryName );
302
351
return bindParameters (session .createNamedQuery (namedQueryName ), params ).executeUpdate ().map (Integer ::longValue );
303
352
});
304
353
305
- return getSession ().chain (session -> bindParameters (
354
+ return getSession (entityClass ).chain (session -> bindParameters (
306
355
session .createMutationQuery (PanacheJpaUtil .createDeleteQuery (entityClass , panacheQuery , paramCount (params ))),
307
356
params )
308
357
.executeUpdate ().map (Integer ::longValue ))
@@ -322,7 +371,7 @@ public IllegalStateException implementationInjectionMissing() {
322
371
public Uni <Integer > executeUpdate (Class <?> entityClass , String panacheQuery , Object ... params ) {
323
372
324
373
if (PanacheJpaUtil .isNamedQuery (panacheQuery ))
325
- return (Uni ) getSession ().chain (session -> {
374
+ return (Uni ) getSession (entityClass ).chain (session -> {
326
375
String namedQueryName = panacheQuery .substring (1 );
327
376
NamedQueryUtil .checkNamedQuery (entityClass , namedQueryName );
328
377
return bindParameters (session .createNamedQuery (namedQueryName ), params ).executeUpdate ();
@@ -337,7 +386,7 @@ public Uni<Integer> executeUpdate(Class<?> entityClass, String panacheQuery, Obj
337
386
public Uni <Integer > executeUpdate (Class <?> entityClass , String panacheQuery , Map <String , Object > params ) {
338
387
339
388
if (PanacheJpaUtil .isNamedQuery (panacheQuery ))
340
- return (Uni ) getSession ().chain (session -> {
389
+ return (Uni ) getSession (entityClass ).chain (session -> {
341
390
String namedQueryName = panacheQuery .substring (1 );
342
391
NamedQueryUtil .checkNamedQuery (entityClass , namedQueryName );
343
392
return bindParameters (session .createNamedQuery (namedQueryName ), params ).executeUpdate ();
@@ -364,8 +413,22 @@ public Uni<Integer> update(Class<?> entityClass, String query, Object... params)
364
413
//
365
414
// Static helpers
366
415
416
+ public static Uni <List <Session >> allSessions () {
417
+ return SessionOperations .allSessions ();
418
+ }
419
+
367
420
public static Uni <Mutiny .Session > getSession () {
368
- return SessionOperations .getSession ();
421
+ return getSession (DEFAULT_PERSISTENCE_UNIT_NAME );
422
+ }
423
+
424
+ public static Uni <Mutiny .Session > getSession (Class <?> clazz ) {
425
+ String className = clazz .getName ();
426
+ String persistenceUnitName = entityToPersistenceUnit .get (className );
427
+ return getSession (persistenceUnitName );
428
+ }
429
+
430
+ public static Uni <Mutiny .Session > getSession (String persistenceUnitName ) {
431
+ return SessionOperations .getSession (persistenceUnitName );
369
432
}
370
433
371
434
public static Mutiny .Query <?> bindParameters (Mutiny .Query <?> query , Object [] params ) {
@@ -395,13 +458,21 @@ public static <T extends Mutiny.AbstractQuery> T bindParameters(T query, Map<Str
395
458
return query ;
396
459
}
397
460
461
+ /**
462
+ * Execute update on default persistence unit
463
+ */
398
464
public static Uni <Integer > executeUpdate (String query , Object ... params ) {
399
- return getSession ().chain (session -> bindParameters (session .createMutationQuery (query ), params )
400
- .executeUpdate ());
465
+ return getSession (DEFAULT_PERSISTENCE_UNIT_NAME )
466
+ .chain (session -> bindParameters (session .createMutationQuery (query ), params )
467
+ .executeUpdate ());
401
468
}
402
469
470
+ /**
471
+ * Execute update on default persistence unit
472
+ */
403
473
public static Uni <Integer > executeUpdate (String query , Map <String , Object > params ) {
404
- return getSession ().chain (session -> bindParameters (session .createMutationQuery (query ), params )
405
- .executeUpdate ());
474
+ return getSession (DEFAULT_PERSISTENCE_UNIT_NAME )
475
+ .chain (session -> bindParameters (session .createMutationQuery (query ), params )
476
+ .executeUpdate ());
406
477
}
407
478
}
0 commit comments