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,50 +69,57 @@ class DefaultNeo4jClient implements Neo4jClient {
7169 new Neo4jConversions ().registerConvertersIn ((ConverterRegistry ) conversionService );
7270 }
7371
74- AutoCloseableQueryRunner getQueryRunner (@ Nullable final String targetDatabase ) {
72+ QueryRunner 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+ private static class DelegatingQueryRunner implements QueryRunner {
83+
84+ private final QueryRunner delegate ;
85+
86+ private DelegatingQueryRunner (QueryRunner delegate ) {
87+ this .delegate = delegate ;
88+ }
8989
9090 @ Override
91- void close ();
92- }
91+ public void close () throws Exception {
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+ 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
102- @ Nullable
103110 @ 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+ }
105114
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 );
118123 }
119124 }
120125
@@ -159,7 +164,7 @@ static class RunnableStatement {
159164
160165 private final NamedParameters parameters ;
161166
162- protected final Result runWith (AutoCloseableQueryRunner statementRunner ) {
167+ protected final Result runWith (QueryRunner statementRunner ) {
163168 String statementTemplate = cypherSupplier .get ();
164169
165170 if (cypherLog .isDebugEnabled ()) {
@@ -257,11 +262,13 @@ public RecordFetchSpec<Map<String, Object>> fetch() {
257262 @ Override
258263 public ResultSummary run () {
259264
260- try (AutoCloseableQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
265+ try (QueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
261266 Result result = runnableStatement .runWith (statementRunner );
262267 return ResultSummaries .process (result .consume ());
263268 } catch (RuntimeException e ) {
264269 throw potentiallyConvertRuntimeException (e , persistenceExceptionTranslator );
270+ } catch (Exception e ) {
271+ throw new RuntimeException (e );
265272 }
266273 }
267274
@@ -306,7 +313,7 @@ public RecordFetchSpec<T> mappedBy(
306313 @ Override
307314 public Optional <T > one () {
308315
309- try (AutoCloseableQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
316+ try (QueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
310317 Result result = runnableStatement .runWith (statementRunner );
311318 Optional <T > optionalValue = result .hasNext () ?
312319 Optional .ofNullable (mappingFunction .apply (typeSystem , result .single ())) :
@@ -315,32 +322,38 @@ public Optional<T> one() {
315322 return optionalValue ;
316323 } catch (RuntimeException e ) {
317324 throw potentiallyConvertRuntimeException (e , persistenceExceptionTranslator );
325+ } catch (Exception e ) {
326+ throw new RuntimeException (e );
318327 }
319328 }
320329
321330 @ Override
322331 public Optional <T > first () {
323332
324- try (AutoCloseableQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
333+ try (QueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
325334 Result result = runnableStatement .runWith (statementRunner );
326335 Optional <T > optionalValue = result .stream ().map (partialMappingFunction (typeSystem )).findFirst ();
327336 ResultSummaries .process (result .consume ());
328337 return optionalValue ;
329338 } catch (RuntimeException e ) {
330339 throw potentiallyConvertRuntimeException (e , persistenceExceptionTranslator );
340+ } catch (Exception e ) {
341+ throw new RuntimeException (e );
331342 }
332343 }
333344
334345 @ Override
335346 public Collection <T > all () {
336347
337- try (AutoCloseableQueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
348+ try (QueryRunner statementRunner = getQueryRunner (this .targetDatabase )) {
338349 Result result = runnableStatement .runWith (statementRunner );
339350 Collection <T > values = result .stream ().map (partialMappingFunction (typeSystem )).collect (Collectors .toList ());
340351 ResultSummaries .process (result .consume ());
341352 return values ;
342353 } catch (RuntimeException e ) {
343354 throw potentiallyConvertRuntimeException (e , persistenceExceptionTranslator );
355+ } catch (Exception e ) {
356+ throw new RuntimeException (e );
344357 }
345358 }
346359
@@ -377,8 +390,12 @@ public RunnableDelegation<T> in(@Nullable @SuppressWarnings("HiddenField") Strin
377390
378391 @ Override
379392 public Optional <T > run () {
380- try (AutoCloseableQueryRunner queryRunner = getQueryRunner (targetDatabase )) {
393+ try (QueryRunner queryRunner = getQueryRunner (targetDatabase )) {
381394 return callback .apply (queryRunner );
395+ } catch (RuntimeException e ) {
396+ throw potentiallyConvertRuntimeException (e , persistenceExceptionTranslator );
397+ } catch (Exception e ) {
398+ throw new RuntimeException (e );
382399 }
383400 }
384401 }
0 commit comments