15
15
*/
16
16
package org .springframework .data .neo4j .core ;
17
17
18
- import java .lang .reflect .InvocationHandler ;
19
- import java .lang .reflect .InvocationTargetException ;
20
- import java .lang .reflect .Method ;
21
- import java .lang .reflect .Proxy ;
22
18
import java .util .Collection ;
23
19
import java .util .Map ;
24
20
import java .util .Optional ;
28
24
import java .util .stream .Collectors ;
29
25
30
26
import org .neo4j .driver .Driver ;
27
+ import org .neo4j .driver .Query ;
31
28
import org .neo4j .driver .QueryRunner ;
32
29
import org .neo4j .driver .Record ;
33
30
import org .neo4j .driver .Result ;
34
31
import org .neo4j .driver .Session ;
32
+ import org .neo4j .driver .Value ;
35
33
import org .neo4j .driver .summary .ResultSummary ;
36
34
import org .neo4j .driver .types .TypeSystem ;
37
35
import org .springframework .core .convert .ConversionService ;
@@ -69,49 +67,57 @@ class DefaultNeo4jClient implements Neo4jClient {
69
67
new Neo4jConversions ().registerConvertersIn ((ConverterRegistry ) conversionService );
70
68
}
71
69
72
- AutoCloseableQueryRunner getQueryRunner (@ Nullable final String targetDatabase ) {
70
+ DelegatingQueryRunner getQueryRunner (@ Nullable final String targetDatabase ) {
73
71
74
72
QueryRunner queryRunner = Neo4jTransactionManager .retrieveTransaction (driver , targetDatabase );
75
73
if (queryRunner == null ) {
76
74
queryRunner = driver .session (Neo4jTransactionUtils .defaultSessionConfig (targetDatabase ));
77
75
}
78
76
79
- return (AutoCloseableQueryRunner ) Proxy .newProxyInstance (this .getClass ().getClassLoader (),
80
- new Class <?>[] { AutoCloseableQueryRunner .class }, new AutoCloseableQueryRunnerHandler (queryRunner ));
77
+ return new DelegatingQueryRunner (queryRunner );
81
78
}
82
79
83
- /**
84
- * Makes a query runner automatically closeable and aware whether it's session or a transaction
85
- */
86
- interface AutoCloseableQueryRunner extends QueryRunner , AutoCloseable {
80
+ static class DelegatingQueryRunner implements QueryRunner , AutoCloseable {
81
+
82
+ private final QueryRunner delegate ;
83
+
84
+ DelegatingQueryRunner (QueryRunner delegate ) {
85
+ this .delegate = delegate ;
86
+ }
87
87
88
88
@ Override
89
- void close ();
90
- }
89
+ public void close () {
91
90
92
- static class AutoCloseableQueryRunnerHandler implements InvocationHandler {
91
+ // We're only going to close sessions we have acquired inside the client, not something that
92
+ // has been retrieved from the tx manager.
93
+ if (this .delegate instanceof Session ) {
94
+ ((Session ) this .delegate ).close ();
95
+ }
96
+ }
93
97
94
- private final QueryRunner target ;
98
+ @ Override
99
+ public Result run (String s , Value value ) {
100
+ return delegate .run (s , value );
101
+ }
95
102
96
- AutoCloseableQueryRunnerHandler (QueryRunner target ) {
97
- this .target = target ;
103
+ @ Override
104
+ public Result run (String s , Map <String , Object > map ) {
105
+ return delegate .run (s , map );
98
106
}
99
107
100
108
@ Override
101
- public Object invoke (Object proxy , Method method , Object [] args ) throws Throwable {
109
+ public Result run (String s , Record record ) {
110
+ return delegate .run (s , record );
111
+ }
102
112
103
- if ("close" .equals (method .getName ())) {
104
- if (this .target instanceof Session ) {
105
- ((Session ) this .target ).close ();
106
- }
107
- return null ;
108
- } else {
109
- try {
110
- return method .invoke (target , args );
111
- } catch (InvocationTargetException ite ) {
112
- throw ite .getCause ();
113
- }
114
- }
113
+ @ Override
114
+ public Result run (String s ) {
115
+ return delegate .run (s );
116
+ }
117
+
118
+ @ Override
119
+ public Result run (Query query ) {
120
+ return delegate .run (query );
115
121
}
116
122
}
117
123
@@ -151,7 +157,7 @@ class RunnableStatement {
151
157
152
158
private final NamedParameters parameters ;
153
159
154
- protected final Result runWith (AutoCloseableQueryRunner statementRunner ) {
160
+ protected final Result runWith (QueryRunner statementRunner ) {
155
161
String statementTemplate = cypherSupplier .get ();
156
162
157
163
if (cypherLog .isDebugEnabled ()) {
@@ -248,7 +254,7 @@ public RecordFetchSpec<Map<String, Object>> fetch() {
248
254
@ Override
249
255
public ResultSummary run () {
250
256
251
- try (AutoCloseableQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
257
+ try (DelegatingQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
252
258
Result result = runnableStatement .runWith (statementRunner );
253
259
return ResultSummaries .process (result .consume ());
254
260
} catch (RuntimeException e ) {
@@ -283,7 +289,7 @@ public RecordFetchSpec<T> mappedBy(
283
289
@ Override
284
290
public Optional <T > one () {
285
291
286
- try (AutoCloseableQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
292
+ try (DelegatingQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
287
293
Result result = runnableStatement .runWith (statementRunner );
288
294
Optional <T > optionalValue = result .hasNext () ?
289
295
Optional .ofNullable (mappingFunction .apply (typeSystem , result .single ())) :
@@ -298,7 +304,7 @@ public Optional<T> one() {
298
304
@ Override
299
305
public Optional <T > first () {
300
306
301
- try (AutoCloseableQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
307
+ try (DelegatingQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
302
308
Result result = runnableStatement .runWith (statementRunner );
303
309
Optional <T > optionalValue = result .stream ().map (partialMappingFunction (typeSystem )).findFirst ();
304
310
ResultSummaries .process (result .consume ());
@@ -311,7 +317,7 @@ public Optional<T> first() {
311
317
@ Override
312
318
public Collection <T > all () {
313
319
314
- try (AutoCloseableQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
320
+ try (DelegatingQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
315
321
Result result = runnableStatement .runWith (statementRunner );
316
322
Collection <T > values = result .stream ().map (partialMappingFunction (typeSystem )).collect (Collectors .toList ());
317
323
ResultSummaries .process (result .consume ());
@@ -354,8 +360,10 @@ public RunnableDelegation in(@Nullable @SuppressWarnings("HiddenField") String t
354
360
355
361
@ Override
356
362
public Optional <T > run () {
357
- try (AutoCloseableQueryRunner queryRunner = getQueryRunner (targetDatabase )) {
363
+ try (DelegatingQueryRunner queryRunner = getQueryRunner (targetDatabase )) {
358
364
return callback .apply (queryRunner );
365
+ } catch (RuntimeException e ) {
366
+ throw potentiallyConvertRuntimeException (e , persistenceExceptionTranslator );
359
367
}
360
368
}
361
369
}
0 commit comments