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 ;
@@ -69,49 +67,57 @@ class DefaultNeo4jClient implements Neo4jClient {
6967 new Neo4jConversions ().registerConvertersIn ((ConverterRegistry ) conversionService );
7068 }
7169
72- AutoCloseableQueryRunner getQueryRunner (@ Nullable final String targetDatabase ) {
70+ DelegatingQueryRunner getQueryRunner (@ Nullable final String targetDatabase ) {
7371
7472 QueryRunner queryRunner = Neo4jTransactionManager .retrieveTransaction (driver , targetDatabase );
7573 if (queryRunner == null ) {
7674 queryRunner = driver .session (Neo4jTransactionUtils .defaultSessionConfig (targetDatabase ));
7775 }
7876
79- return (AutoCloseableQueryRunner ) Proxy .newProxyInstance (this .getClass ().getClassLoader (),
80- new Class <?>[] { AutoCloseableQueryRunner .class }, new AutoCloseableQueryRunnerHandler (queryRunner ));
77+ return new DelegatingQueryRunner (queryRunner );
8178 }
8279
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+ }
8787
8888 @ Override
89- void close ();
90- }
89+ public void close () {
9190
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+ }
9397
94- private final QueryRunner target ;
98+ @ Override
99+ public Result run (String s , Value value ) {
100+ return delegate .run (s , value );
101+ }
95102
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 );
98106 }
99107
100108 @ 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+ }
102112
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 );
115121 }
116122 }
117123
@@ -151,7 +157,7 @@ class RunnableStatement {
151157
152158 private final NamedParameters parameters ;
153159
154- protected final Result runWith (AutoCloseableQueryRunner statementRunner ) {
160+ protected final Result runWith (QueryRunner statementRunner ) {
155161 String statementTemplate = cypherSupplier .get ();
156162
157163 if (cypherLog .isDebugEnabled ()) {
@@ -248,7 +254,7 @@ public RecordFetchSpec<Map<String, Object>> fetch() {
248254 @ Override
249255 public ResultSummary run () {
250256
251- try (AutoCloseableQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
257+ try (DelegatingQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
252258 Result result = runnableStatement .runWith (statementRunner );
253259 return ResultSummaries .process (result .consume ());
254260 } catch (RuntimeException e ) {
@@ -283,7 +289,7 @@ public RecordFetchSpec<T> mappedBy(
283289 @ Override
284290 public Optional <T > one () {
285291
286- try (AutoCloseableQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
292+ try (DelegatingQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
287293 Result result = runnableStatement .runWith (statementRunner );
288294 Optional <T > optionalValue = result .hasNext () ?
289295 Optional .ofNullable (mappingFunction .apply (typeSystem , result .single ())) :
@@ -298,7 +304,7 @@ public Optional<T> one() {
298304 @ Override
299305 public Optional <T > first () {
300306
301- try (AutoCloseableQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
307+ try (DelegatingQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
302308 Result result = runnableStatement .runWith (statementRunner );
303309 Optional <T > optionalValue = result .stream ().map (partialMappingFunction (typeSystem )).findFirst ();
304310 ResultSummaries .process (result .consume ());
@@ -311,7 +317,7 @@ public Optional<T> first() {
311317 @ Override
312318 public Collection <T > all () {
313319
314- try (AutoCloseableQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
320+ try (DelegatingQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
315321 Result result = runnableStatement .runWith (statementRunner );
316322 Collection <T > values = result .stream ().map (partialMappingFunction (typeSystem )).collect (Collectors .toList ());
317323 ResultSummaries .process (result .consume ());
@@ -354,8 +360,10 @@ public RunnableDelegation in(@Nullable @SuppressWarnings("HiddenField") String t
354360
355361 @ Override
356362 public Optional <T > run () {
357- try (AutoCloseableQueryRunner queryRunner = getQueryRunner (targetDatabase )) {
363+ try (DelegatingQueryRunner queryRunner = getQueryRunner (targetDatabase )) {
358364 return callback .apply (queryRunner );
365+ } catch (RuntimeException e ) {
366+ throw potentiallyConvertRuntimeException (e , persistenceExceptionTranslator );
359367 }
360368 }
361369 }
0 commit comments