1
1
package io .quarkus .hibernate .reactive .panache .common .runtime ;
2
2
3
+ import static org .hibernate .reactive .context .impl .ContextualDataStorage .contextualDataMap ;
4
+
5
+ import java .util .Map ;
3
6
import java .util .function .Function ;
4
7
import java .util .function .Supplier ;
5
8
6
9
import org .hibernate .reactive .common .spi .Implementor ;
7
10
import org .hibernate .reactive .context .Context .Key ;
8
11
import org .hibernate .reactive .context .impl .BaseKey ;
12
+ import org .hibernate .reactive .context .impl .ContextualDataStorage ;
9
13
import org .hibernate .reactive .mutiny .Mutiny ;
10
14
import org .hibernate .reactive .mutiny .Mutiny .Session ;
11
- import org .hibernate .reactive .mutiny .Mutiny .SessionFactory ;
12
15
import org .hibernate .reactive .mutiny .Mutiny .Transaction ;
13
16
14
17
import io .quarkus .arc .Arc ;
15
18
import io .quarkus .arc .ClientProxy ;
16
19
import io .quarkus .arc .impl .LazyValue ;
17
20
import io .quarkus .vertx .core .runtime .context .VertxContextSafetyToggle ;
18
21
import io .smallrye .mutiny .Uni ;
19
- import io .vertx .core .Context ;
20
- import io .vertx .core .Vertx ;
22
+ import io .vertx .core .impl .ContextInternal ;
21
23
22
24
/**
23
25
* Static util methods for {@link Mutiny.Session}.
@@ -29,7 +31,7 @@ public final class SessionOperations {
29
31
private static final LazyValue <Mutiny .SessionFactory > SESSION_FACTORY = new LazyValue <>(
30
32
new Supplier <Mutiny .SessionFactory >() {
31
33
@ Override
32
- public SessionFactory get () {
34
+ public Mutiny . SessionFactory get () {
33
35
// Note that Mutiny.SessionFactory is @ApplicationScoped bean - it's safe to use the cached client proxy
34
36
Mutiny .SessionFactory sessionFactory = Arc .container ().instance (Mutiny .SessionFactory .class ).get ();
35
37
if (sessionFactory == null ) {
@@ -50,8 +52,10 @@ public Key<Session> get() {
50
52
});
51
53
52
54
// This key is used to indicate that a reactive session should be opened lazily (when needed) in the current vertx context
53
- private static final String SESSION_ON_DEMAND_KEY = "hibernate.reactive.panache.sessionOnDemand" ;
54
- private static final String SESSION_ON_DEMAND_OPENED_KEY = "hibernate.reactive.panache.sessionOnDemandOpened" ;
55
+ private static final Key <Boolean > SESSION_ON_DEMAND_KEY = new BaseKey <>(Boolean .class ,
56
+ "hibernate.reactive.panache.sessionOnDemand" );
57
+ private static final Key <Boolean > SESSION_ON_DEMAND_OPENED_KEY = new BaseKey <>(Boolean .class ,
58
+ "hibernate.reactive.panache.sessionOnDemandOpened" );
55
59
56
60
/**
57
61
* Marks the current vertx duplicated context as "lazy" which indicates that a reactive session should be opened lazily if
@@ -63,17 +67,17 @@ public Key<Session> get() {
63
67
* @see #getSession()
64
68
*/
65
69
static <T > Uni <T > withSessionOnDemand (Supplier <Uni <T >> work ) {
66
- Context context = vertxContext ();
67
- if (context . getLocal (SESSION_ON_DEMAND_KEY ) != null ) {
70
+ Map < Key < Boolean >, Boolean > contextualDataMap = contextualDataMap ( vertxContext () );
71
+ if (contextualDataMap . get (SESSION_ON_DEMAND_KEY ) != null ) {
68
72
// context already marked - no need to set the key and close the session
69
73
return work .get ();
70
74
} else {
71
75
// mark the lazy session
72
- context . putLocal (SESSION_ON_DEMAND_KEY , true );
76
+ contextualDataMap . put (SESSION_ON_DEMAND_KEY , Boolean . TRUE );
73
77
// perform the work and eventually close the session and remove the key
74
78
return work .get ().eventually (() -> {
75
- context . removeLocal (SESSION_ON_DEMAND_KEY );
76
- context . removeLocal (SESSION_ON_DEMAND_OPENED_KEY );
79
+ contextualDataMap . remove (SESSION_ON_DEMAND_KEY );
80
+ contextualDataMap . remove (SESSION_ON_DEMAND_OPENED_KEY );
77
81
return closeSession ();
78
82
});
79
83
}
@@ -109,17 +113,17 @@ public static <T> Uni<T> withTransaction(Function<Transaction, Uni<T>> work) {
109
113
* @return a new {@link Uni}
110
114
*/
111
115
public static <T > Uni <T > withSession (Function <Mutiny .Session , Uni <T >> work ) {
112
- Context context = vertxContext ();
116
+ Map < Key < Session >, Session > contextualDataMap = contextualDataMap ( vertxContext () );
113
117
Key <Mutiny .Session > key = getSessionKey ();
114
- Mutiny .Session current = context . getLocal (key );
118
+ Mutiny .Session current = contextualDataMap . get (key );
115
119
if (current != null && current .isOpen ()) {
116
120
// reactive session exists - reuse this session
117
121
return work .apply (current );
118
122
} else {
119
123
// reactive session does not exist - open a new one and close it when the returned Uni completes
120
124
return getSessionFactory ()
121
125
.openSession ()
122
- .invoke (s -> context . putLocal (key , s ))
126
+ .invoke (s -> contextualDataMap . put (key , s ))
123
127
.chain (work ::apply )
124
128
.eventually (SessionOperations ::closeSession );
125
129
}
@@ -140,22 +144,24 @@ public static <T> Uni<T> withSession(Function<Mutiny.Session, Uni<T>> work) {
140
144
* @return the {@link Mutiny.Session}
141
145
*/
142
146
public static Uni <Mutiny .Session > getSession () {
143
- Context context = vertxContext ();
144
- Key <Mutiny .Session > key = getSessionKey ();
145
- Mutiny .Session current = context .getLocal (key );
147
+ final ContextInternal context = vertxContext ();
148
+ final Key <Mutiny .Session > key = getSessionKey ();
149
+ final Mutiny .Session current = ContextualDataStorage .<Session > contextualDataMap (context ).get (key );
150
+ final Map <Key <Boolean >, Boolean > objectsDataMap = contextualDataMap (context );
146
151
if (current != null && current .isOpen ()) {
147
152
// reuse the existing reactive session
148
153
return Uni .createFrom ().item (current );
149
154
} else {
150
- if (context . getLocal (SESSION_ON_DEMAND_KEY ) != null ) {
151
- if (context . getLocal (SESSION_ON_DEMAND_OPENED_KEY ) != null ) {
155
+ if (objectsDataMap . get (SESSION_ON_DEMAND_KEY ) != null ) {
156
+ if (objectsDataMap . get (SESSION_ON_DEMAND_OPENED_KEY ) != null ) {
152
157
// a new reactive session is opened in a previous stage
153
158
return Uni .createFrom ().item (SessionOperations ::getCurrentSession );
154
159
} else {
155
160
// open a new reactive session and store it in the vertx duplicated context
156
161
// the context was marked as "lazy" which means that the session will be eventually closed
157
- context .putLocal (SESSION_ON_DEMAND_OPENED_KEY , true );
158
- return getSessionFactory ().openSession ().invoke (s -> context .putLocal (key , s ));
162
+ objectsDataMap .put (SESSION_ON_DEMAND_OPENED_KEY , Boolean .TRUE );
163
+ return getSessionFactory ().openSession ().invoke (s -> ContextualDataStorage
164
+ .<Session > contextualDataMap (context ).put (key , s ));
159
165
}
160
166
} else {
161
167
throw new IllegalStateException ("No current Mutiny.Session found"
@@ -170,8 +176,7 @@ public static Uni<Mutiny.Session> getSession() {
170
176
* @return the current reactive session stored in the context, or {@code null} if no session exists
171
177
*/
172
178
public static Mutiny .Session getCurrentSession () {
173
- Context context = vertxContext ();
174
- Mutiny .Session current = context .getLocal (getSessionKey ());
179
+ Mutiny .Session current = ContextualDataStorage .<Session > contextualDataMap (vertxContext ()).get (getSessionKey ());
175
180
if (current != null && current .isOpen ()) {
176
181
return current ;
177
182
}
@@ -184,8 +189,8 @@ public static Mutiny.Session getCurrentSession() {
184
189
* @throws IllegalStateException If no vertx context is found or is not a safe context as mandated by the
185
190
* {@link VertxContextSafetyToggle}
186
191
*/
187
- private static Context vertxContext () {
188
- Context context = Vertx . currentContext ();
192
+ private static ContextInternal vertxContext () {
193
+ ContextInternal context = ContextInternal . current ();
189
194
if (context != null ) {
190
195
VertxContextSafetyToggle .validateContextIfExists (ERROR_MSG , ERROR_MSG );
191
196
return context ;
@@ -195,11 +200,11 @@ private static Context vertxContext() {
195
200
}
196
201
197
202
static Uni <Void > closeSession () {
198
- Context context = vertxContext ();
199
203
Key <Mutiny .Session > key = getSessionKey ();
200
- Mutiny .Session current = context .getLocal (key );
204
+ Map <Key <Session >, Session > contextualDataMap = contextualDataMap (vertxContext ());
205
+ Mutiny .Session current = contextualDataMap .get (key );
201
206
if (current != null && current .isOpen ()) {
202
- return current .close ().eventually (() -> context . removeLocal (key ));
207
+ return current .close ().eventually (() -> contextualDataMap . remove (key ));
203
208
}
204
209
return Uni .createFrom ().voidItem ();
205
210
}
0 commit comments