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 ;
@@ -71,50 +69,57 @@ class DefaultNeo4jClient implements Neo4jClient {
71
69
new Neo4jConversions ().registerConvertersIn ((ConverterRegistry ) conversionService );
72
70
}
73
71
74
- AutoCloseableQueryRunner getQueryRunner (@ Nullable final String targetDatabase ) {
72
+ QueryRunner getQueryRunner (@ Nullable final String targetDatabase ) {
75
73
76
74
QueryRunner queryRunner = Neo4jTransactionManager .retrieveTransaction (driver , targetDatabase );
77
75
if (queryRunner == null ) {
78
76
queryRunner = driver .session (Neo4jTransactionUtils .defaultSessionConfig (targetDatabase ));
79
77
}
80
78
81
- return (AutoCloseableQueryRunner ) Proxy .newProxyInstance (this .getClass ().getClassLoader (),
82
- new Class <?>[] { AutoCloseableQueryRunner .class }, new AutoCloseableQueryRunnerHandler (queryRunner ));
79
+ return new DelegatingQueryRunner (queryRunner );
83
80
}
84
81
85
- /**
86
- * Makes a query runner automatically closeable and aware whether it's session or a transaction
87
- */
88
- interface AutoCloseableQueryRunner extends QueryRunner , AutoCloseable {
82
+ private static class DelegatingQueryRunner implements QueryRunner {
83
+
84
+ private final QueryRunner delegate ;
85
+
86
+ private DelegatingQueryRunner (QueryRunner delegate ) {
87
+ this .delegate = delegate ;
88
+ }
89
89
90
90
@ Override
91
- void close ();
92
- }
91
+ public void close () throws Exception {
93
92
94
- static class AutoCloseableQueryRunnerHandler implements InvocationHandler {
93
+ // We're only going to close sessions we have acquired inside the client, not something that
94
+ // has been retrieved from the tx manager.
95
+ if (this .delegate instanceof Session ) {
96
+ this .delegate .close ();
97
+ }
98
+ }
95
99
96
- private final QueryRunner target ;
100
+ @ Override
101
+ public Result run (String s , Value value ) {
102
+ return delegate .run (s , value );
103
+ }
97
104
98
- AutoCloseableQueryRunnerHandler (QueryRunner target ) {
99
- this .target = target ;
105
+ @ Override
106
+ public Result run (String s , Map <String , Object > map ) {
107
+ return delegate .run (s , map );
100
108
}
101
109
102
- @ Nullable
103
110
@ Override
104
- public Object invoke (Object proxy , Method method , Object [] args ) throws Throwable {
111
+ public Result run (String s , Record record ) {
112
+ return delegate .run (s , record );
113
+ }
105
114
106
- if ("close" .equals (method .getName ())) {
107
- if (this .target instanceof Session ) {
108
- ((Session ) this .target ).close ();
109
- }
110
- return null ;
111
- } else {
112
- try {
113
- return method .invoke (target , args );
114
- } catch (InvocationTargetException ite ) {
115
- throw ite .getCause ();
116
- }
117
- }
115
+ @ Override
116
+ public Result run (String s ) {
117
+ return delegate .run (s );
118
+ }
119
+
120
+ @ Override
121
+ public Result run (Query query ) {
122
+ return delegate .run (query );
118
123
}
119
124
}
120
125
@@ -159,7 +164,7 @@ static class RunnableStatement {
159
164
160
165
private final NamedParameters parameters ;
161
166
162
- protected final Result runWith (AutoCloseableQueryRunner statementRunner ) {
167
+ protected final Result runWith (QueryRunner statementRunner ) {
163
168
String statementTemplate = cypherSupplier .get ();
164
169
165
170
if (cypherLog .isDebugEnabled ()) {
@@ -257,11 +262,13 @@ public RecordFetchSpec<Map<String, Object>> fetch() {
257
262
@ Override
258
263
public ResultSummary run () {
259
264
260
- try (AutoCloseableQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
265
+ try (QueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
261
266
Result result = runnableStatement .runWith (statementRunner );
262
267
return ResultSummaries .process (result .consume ());
263
268
} catch (RuntimeException e ) {
264
269
throw potentiallyConvertRuntimeException (e , persistenceExceptionTranslator );
270
+ } catch (Exception e ) {
271
+ throw new RuntimeException (e );
265
272
}
266
273
}
267
274
@@ -306,7 +313,7 @@ public RecordFetchSpec<T> mappedBy(
306
313
@ Override
307
314
public Optional <T > one () {
308
315
309
- try (AutoCloseableQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
316
+ try (QueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
310
317
Result result = runnableStatement .runWith (statementRunner );
311
318
Optional <T > optionalValue = result .hasNext () ?
312
319
Optional .ofNullable (mappingFunction .apply (typeSystem , result .single ())) :
@@ -315,32 +322,38 @@ public Optional<T> one() {
315
322
return optionalValue ;
316
323
} catch (RuntimeException e ) {
317
324
throw potentiallyConvertRuntimeException (e , persistenceExceptionTranslator );
325
+ } catch (Exception e ) {
326
+ throw new RuntimeException (e );
318
327
}
319
328
}
320
329
321
330
@ Override
322
331
public Optional <T > first () {
323
332
324
- try (AutoCloseableQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
333
+ try (QueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
325
334
Result result = runnableStatement .runWith (statementRunner );
326
335
Optional <T > optionalValue = result .stream ().map (partialMappingFunction (typeSystem )).findFirst ();
327
336
ResultSummaries .process (result .consume ());
328
337
return optionalValue ;
329
338
} catch (RuntimeException e ) {
330
339
throw potentiallyConvertRuntimeException (e , persistenceExceptionTranslator );
340
+ } catch (Exception e ) {
341
+ throw new RuntimeException (e );
331
342
}
332
343
}
333
344
334
345
@ Override
335
346
public Collection <T > all () {
336
347
337
- try (AutoCloseableQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
348
+ try (QueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
338
349
Result result = runnableStatement .runWith (statementRunner );
339
350
Collection <T > values = result .stream ().map (partialMappingFunction (typeSystem )).collect (Collectors .toList ());
340
351
ResultSummaries .process (result .consume ());
341
352
return values ;
342
353
} catch (RuntimeException e ) {
343
354
throw potentiallyConvertRuntimeException (e , persistenceExceptionTranslator );
355
+ } catch (Exception e ) {
356
+ throw new RuntimeException (e );
344
357
}
345
358
}
346
359
@@ -377,8 +390,12 @@ public RunnableDelegation<T> in(@Nullable @SuppressWarnings("HiddenField") Strin
377
390
378
391
@ Override
379
392
public Optional <T > run () {
380
- try (AutoCloseableQueryRunner queryRunner = getQueryRunner (targetDatabase )) {
393
+ try (QueryRunner queryRunner = getQueryRunner (targetDatabase )) {
381
394
return callback .apply (queryRunner );
395
+ } catch (RuntimeException e ) {
396
+ throw potentiallyConvertRuntimeException (e , persistenceExceptionTranslator );
397
+ } catch (Exception e ) {
398
+ throw new RuntimeException (e );
382
399
}
383
400
}
384
401
}
0 commit comments