1515 */
1616package org .springframework .data .neo4j .core ;
1717
18- import java .lang .reflect .InvocationHandler ;
19- import java .lang .reflect .InvocationTargetException ;
20- import java .lang .reflect .Method ;
21- import java .lang .reflect .Proxy ;
2218import java .util .Collection ;
2319import java .util .Map ;
2420import java .util .Optional ;
2824import java .util .stream .Collectors ;
2925
3026import org .neo4j .driver .Driver ;
27+ import org .neo4j .driver .Query ;
3128import org .neo4j .driver .QueryRunner ;
3229import org .neo4j .driver .Record ;
3330import org .neo4j .driver .Result ;
3431import org .neo4j .driver .Session ;
32+ import org .neo4j .driver .Value ;
3533import org .neo4j .driver .summary .ResultSummary ;
3634import org .neo4j .driver .types .TypeSystem ;
3735import org .springframework .core .convert .ConversionService ;
@@ -71,49 +69,57 @@ class DefaultNeo4jClient implements Neo4jClient {
7169 new Neo4jConversions ().registerConvertersIn ((ConverterRegistry ) conversionService );
7270 }
7371
74- AutoCloseableQueryRunner getQueryRunner (@ Nullable final String targetDatabase ) {
72+ DelegatingQueryRunner getQueryRunner (@ Nullable final String targetDatabase ) {
7573
7674 QueryRunner queryRunner = Neo4jTransactionManager .retrieveTransaction (driver , targetDatabase );
7775 if (queryRunner == null ) {
7876 queryRunner = driver .session (Neo4jTransactionUtils .defaultSessionConfig (targetDatabase ));
7977 }
8078
81- return (AutoCloseableQueryRunner ) Proxy .newProxyInstance (this .getClass ().getClassLoader (),
82- new Class <?>[] { AutoCloseableQueryRunner .class }, new AutoCloseableQueryRunnerHandler (queryRunner ));
79+ return new DelegatingQueryRunner (queryRunner );
8380 }
8481
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+ static class DelegatingQueryRunner implements QueryRunner , AutoCloseable {
83+
84+ private final QueryRunner delegate ;
85+
86+ DelegatingQueryRunner (QueryRunner delegate ) {
87+ this .delegate = delegate ;
88+ }
8989
9090 @ Override
91- void close ();
92- }
91+ public void close () {
9392
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+ ((Session ) this .delegate ).close ();
97+ }
98+ }
9599
96- private final QueryRunner target ;
100+ @ Override
101+ public Result run (String s , Value value ) {
102+ return delegate .run (s , value );
103+ }
97104
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 );
100108 }
101109
102110 @ Override
103- 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+ }
104114
105- if ("close" .equals (method .getName ())) {
106- if (this .target instanceof Session ) {
107- ((Session ) this .target ).close ();
108- }
109- return null ;
110- } else {
111- try {
112- return method .invoke (target , args );
113- } catch (InvocationTargetException ite ) {
114- throw ite .getCause ();
115- }
116- }
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 );
117123 }
118124 }
119125
@@ -158,7 +164,7 @@ class RunnableStatement {
158164
159165 private final NamedParameters parameters ;
160166
161- protected final Result runWith (AutoCloseableQueryRunner statementRunner ) {
167+ protected final Result runWith (QueryRunner statementRunner ) {
162168 String statementTemplate = cypherSupplier .get ();
163169
164170 if (cypherLog .isDebugEnabled ()) {
@@ -256,7 +262,7 @@ public RecordFetchSpec<Map<String, Object>> fetch() {
256262 @ Override
257263 public ResultSummary run () {
258264
259- try (AutoCloseableQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
265+ try (DelegatingQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
260266 Result result = runnableStatement .runWith (statementRunner );
261267 return ResultSummaries .process (result .consume ());
262268 } catch (RuntimeException e ) {
@@ -305,7 +311,7 @@ public RecordFetchSpec<T> mappedBy(
305311 @ Override
306312 public Optional <T > one () {
307313
308- try (AutoCloseableQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
314+ try (DelegatingQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
309315 Result result = runnableStatement .runWith (statementRunner );
310316 Optional <T > optionalValue = result .hasNext () ?
311317 Optional .ofNullable (mappingFunction .apply (typeSystem , result .single ())) :
@@ -320,7 +326,7 @@ public Optional<T> one() {
320326 @ Override
321327 public Optional <T > first () {
322328
323- try (AutoCloseableQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
329+ try (DelegatingQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
324330 Result result = runnableStatement .runWith (statementRunner );
325331 Optional <T > optionalValue = result .stream ().map (partialMappingFunction (typeSystem )).findFirst ();
326332 ResultSummaries .process (result .consume ());
@@ -333,7 +339,7 @@ public Optional<T> first() {
333339 @ Override
334340 public Collection <T > all () {
335341
336- try (AutoCloseableQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
342+ try (DelegatingQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
337343 Result result = runnableStatement .runWith (statementRunner );
338344 Collection <T > values = result .stream ().map (partialMappingFunction (typeSystem )).collect (Collectors .toList ());
339345 ResultSummaries .process (result .consume ());
@@ -376,8 +382,10 @@ public RunnableDelegation in(@Nullable @SuppressWarnings("HiddenField") String t
376382
377383 @ Override
378384 public Optional <T > run () {
379- try (AutoCloseableQueryRunner queryRunner = getQueryRunner (targetDatabase )) {
385+ try (DelegatingQueryRunner queryRunner = getQueryRunner (targetDatabase )) {
380386 return callback .apply (queryRunner );
387+ } catch (RuntimeException e ) {
388+ throw potentiallyConvertRuntimeException (e , persistenceExceptionTranslator );
381389 }
382390 }
383391 }
0 commit comments