@@ -216,7 +216,7 @@ public long count(String cypherQuery, Map<String, Object> parameters) {
216
216
return transactionTemplateReadOnly .execute (tx -> {
217
217
PreparedQuery <Long > preparedQuery = PreparedQuery .queryFor (Long .class ).withCypherQuery (cypherQuery )
218
218
.withParameters (parameters ).build ();
219
- return toExecutableQuery (preparedQuery ).getRequiredSingleResult ();
219
+ return toExecutableQuery (preparedQuery , true ).getRequiredSingleResult ();
220
220
});
221
221
}
222
222
@@ -230,45 +230,46 @@ private <T> List<T> doFindAll(Class<T> domainType, @Nullable Class<?> resultType
230
230
return transactionTemplateReadOnly
231
231
.execute (tx -> {
232
232
Neo4jPersistentEntity <?> entityMetaData = neo4jMappingContext .getRequiredPersistentEntity (domainType );
233
- return createExecutableQuery (domainType , resultType , QueryFragmentsAndParameters .forFindAll (entityMetaData ))
233
+ return createExecutableQuery (
234
+ domainType , resultType , QueryFragmentsAndParameters .forFindAll (entityMetaData ), true )
234
235
.getResults ();
235
236
});
236
237
}
237
238
238
239
@ Override
239
240
public <T > List <T > findAll (Statement statement , Class <T > domainType ) {
240
241
return transactionTemplateReadOnly
241
- .execute (tx -> createExecutableQuery (domainType , statement ).getResults ());
242
+ .execute (tx -> createExecutableQuery (domainType , statement , true ).getResults ());
242
243
}
243
244
244
245
@ Override
245
246
public <T > List <T > findAll (Statement statement , Map <String , Object > parameters , Class <T > domainType ) {
246
247
return transactionTemplateReadOnly
247
- .execute (tx -> createExecutableQuery (domainType , null , statement , parameters ).getResults ());
248
+ .execute (tx -> createExecutableQuery (domainType , null , statement , parameters , true ).getResults ());
248
249
}
249
250
250
251
@ Override
251
252
public <T > Optional <T > findOne (Statement statement , Map <String , Object > parameters , Class <T > domainType ) {
252
253
return transactionTemplateReadOnly
253
- .execute (tx -> createExecutableQuery (domainType , null , statement , parameters ).getSingleResult ());
254
+ .execute (tx -> createExecutableQuery (domainType , null , statement , parameters , true ).getSingleResult ());
254
255
}
255
256
256
257
@ Override
257
258
public <T > List <T > findAll (String cypherQuery , Class <T > domainType ) {
258
259
return transactionTemplateReadOnly
259
- .execute (tx -> createExecutableQuery (domainType , cypherQuery ).getResults ());
260
+ .execute (tx -> createExecutableQuery (domainType , cypherQuery , true ).getResults ());
260
261
}
261
262
262
263
@ Override
263
264
public <T > List <T > findAll (String cypherQuery , Map <String , Object > parameters , Class <T > domainType ) {
264
265
return transactionTemplateReadOnly
265
- .execute (tx -> createExecutableQuery (domainType , null , cypherQuery , parameters ).getResults ());
266
+ .execute (tx -> createExecutableQuery (domainType , null , cypherQuery , parameters , true ).getResults ());
266
267
}
267
268
268
269
@ Override
269
270
public <T > Optional <T > findOne (String cypherQuery , Map <String , Object > parameters , Class <T > domainType ) {
270
271
return transactionTemplateReadOnly
271
- .execute (tx -> createExecutableQuery (domainType , null , cypherQuery , parameters ).getSingleResult ());
272
+ .execute (tx -> createExecutableQuery (domainType , null , cypherQuery , parameters , true ).getSingleResult ());
272
273
}
273
274
274
275
@ Override
@@ -288,9 +289,10 @@ <T, R> List<R> doFind(@Nullable String cypherQuery, @Nullable Map<String, Object
288
289
ExecutableQuery <T > executableQuery ;
289
290
if (queryFragmentsAndParameters == null ) {
290
291
executableQuery = createExecutableQuery (domainType , resultType , cypherQuery ,
291
- parameters == null ? Collections .emptyMap () : parameters );
292
+ parameters == null ? Collections .emptyMap () : parameters ,
293
+ true );
292
294
} else {
293
- executableQuery = createExecutableQuery (domainType , resultType , queryFragmentsAndParameters );
295
+ executableQuery = createExecutableQuery (domainType , resultType , queryFragmentsAndParameters , true );
294
296
}
295
297
intermediaResults = switch (fetchType ) {
296
298
case ALL -> executableQuery .getResults ();
@@ -341,7 +343,8 @@ public <T> Optional<T> findById(Object id, Class<T> domainType) {
341
343
342
344
return createExecutableQuery (domainType , null ,
343
345
QueryFragmentsAndParameters .forFindById (entityMetaData ,
344
- convertIdValues (entityMetaData .getRequiredIdProperty (), id )))
346
+ convertIdValues (entityMetaData .getRequiredIdProperty (), id )),
347
+ true )
345
348
.getSingleResult ();
346
349
});
347
350
}
@@ -354,7 +357,8 @@ public <T> List<T> findAllById(Iterable<?> ids, Class<T> domainType) {
354
357
355
358
return createExecutableQuery (domainType , null ,
356
359
QueryFragmentsAndParameters .forFindByAllId (
357
- entityMetaData , convertIdValues (entityMetaData .getRequiredIdProperty (), ids )))
360
+ entityMetaData , convertIdValues (entityMetaData .getRequiredIdProperty (), ids )),
361
+ true )
358
362
.getResults ();
359
363
});
360
364
}
@@ -697,7 +701,7 @@ public <T> void deleteByIdWithVersion(Object id, Class<T> domainType, Neo4jPersi
697
701
parameters .put (nameOfParameter , convertIdValues (entityMetaData .getRequiredIdProperty (), id ));
698
702
parameters .put (Constants .NAME_OF_VERSION_PARAM , versionValue );
699
703
700
- createExecutableQuery (domainType , null , statement , parameters ).getSingleResult ().orElseThrow (
704
+ createExecutableQuery (domainType , null , statement , parameters , false ).getSingleResult ().orElseThrow (
701
705
() -> new OptimisticLockingFailureException (OPTIMISTIC_LOCKING_ERROR_MESSAGE )
702
706
);
703
707
@@ -744,21 +748,24 @@ public void deleteAll(Class<?> domainType) {
744
748
});
745
749
}
746
750
747
- private <T > ExecutableQuery <T > createExecutableQuery (Class <T > domainType , Statement statement ) {
748
- return createExecutableQuery (domainType , null , statement , Collections .emptyMap ());
751
+ private <T > ExecutableQuery <T > createExecutableQuery (Class <T > domainType , Statement statement , boolean readOnly ) {
752
+ return createExecutableQuery (domainType , null , statement , Collections .emptyMap (), readOnly );
749
753
}
750
754
751
- private <T > ExecutableQuery <T > createExecutableQuery (Class <T > domainType , String cypherQuery ) {
752
- return createExecutableQuery (domainType , null , cypherQuery , Collections .emptyMap ());
755
+ private <T > ExecutableQuery <T > createExecutableQuery (Class <T > domainType , String cypherQuery , boolean readOnly ) {
756
+ return createExecutableQuery (domainType , null , cypherQuery , Collections .emptyMap (), readOnly );
753
757
}
754
758
755
- private <T > ExecutableQuery <T > createExecutableQuery (Class <T > domainType , @ Nullable Class <?> resultType , Statement statement , Map <String , Object > parameters ) {
759
+ private <T > ExecutableQuery <T > createExecutableQuery (Class <T > domainType , @ Nullable Class <?> resultType , Statement statement , Map <String , Object > parameters , boolean readOnly ) {
756
760
757
- return createExecutableQuery (domainType , resultType , renderer .render (statement ), TemplateSupport .mergeParameters (statement , parameters ));
761
+ return createExecutableQuery (domainType , resultType , renderer .render (statement ), TemplateSupport .mergeParameters (statement , parameters ), readOnly );
758
762
}
759
763
760
- private <T > ExecutableQuery <T > createExecutableQuery (Class <T > domainType , @ Nullable Class <?> resultType , @ Nullable String cypherStatement ,
761
- Map <String , Object > parameters ) {
764
+ private <T > ExecutableQuery <T > createExecutableQuery (
765
+ Class <T > domainType , @ Nullable Class <?> resultType ,
766
+ @ Nullable String cypherStatement ,
767
+ Map <String , Object > parameters ,
768
+ boolean readOnly ) {
762
769
763
770
Supplier <BiFunction <TypeSystem , MapAccessor , ?>> mappingFunction = TemplateSupport
764
771
.getAndDecorateMappingFunction (neo4jMappingContext , domainType , resultType );
@@ -768,7 +775,7 @@ private <T> ExecutableQuery<T> createExecutableQuery(Class<T> domainType, @Nulla
768
775
.usingMappingFunction (mappingFunction )
769
776
.build ();
770
777
771
- return toExecutableQuery (preparedQuery );
778
+ return toExecutableQuery (preparedQuery , readOnly );
772
779
}
773
780
774
781
/**
@@ -1191,26 +1198,31 @@ public void setTransactionManager(@Nullable PlatformTransactionManager transacti
1191
1198
public <T > ExecutableQuery <T > toExecutableQuery (Class <T > domainType ,
1192
1199
QueryFragmentsAndParameters queryFragmentsAndParameters ) {
1193
1200
1194
- return createExecutableQuery (domainType , null , queryFragmentsAndParameters );
1201
+ return createExecutableQuery (domainType , null , queryFragmentsAndParameters , false );
1195
1202
}
1196
1203
1197
1204
1198
- private <T > ExecutableQuery <T > createExecutableQuery (Class <T > domainType , @ Nullable Class <?> resultType ,
1199
- QueryFragmentsAndParameters queryFragmentsAndParameters ) {
1205
+ private <T > ExecutableQuery <T > createExecutableQuery (
1206
+ Class <T > domainType , @ Nullable Class <?> resultType ,
1207
+ QueryFragmentsAndParameters queryFragmentsAndParameters ,
1208
+ boolean readOnlyTransaction ) {
1200
1209
1201
1210
Supplier <BiFunction <TypeSystem , MapAccessor , ?>> mappingFunction = TemplateSupport
1202
1211
.getAndDecorateMappingFunction (neo4jMappingContext , domainType , resultType );
1203
1212
PreparedQuery <T > preparedQuery = PreparedQuery .queryFor (domainType )
1204
1213
.withQueryFragmentsAndParameters (queryFragmentsAndParameters )
1205
1214
.usingMappingFunction (mappingFunction )
1206
1215
.build ();
1207
- return toExecutableQuery (preparedQuery );
1216
+ return toExecutableQuery (preparedQuery , readOnlyTransaction );
1208
1217
}
1209
1218
1210
1219
@ Override
1211
1220
public <T > ExecutableQuery <T > toExecutableQuery (PreparedQuery <T > preparedQuery ) {
1221
+ return toExecutableQuery (preparedQuery , false );
1222
+ }
1212
1223
1213
- return new DefaultExecutableQuery <>(preparedQuery );
1224
+ private <T > ExecutableQuery <T > toExecutableQuery (PreparedQuery <T > preparedQuery , boolean readOnly ) {
1225
+ return new DefaultExecutableQuery <>(preparedQuery , readOnly );
1214
1226
}
1215
1227
1216
1228
@ Override
@@ -1255,14 +1267,17 @@ String render(Statement statement) {
1255
1267
final class DefaultExecutableQuery <T > implements ExecutableQuery <T > {
1256
1268
1257
1269
private final PreparedQuery <T > preparedQuery ;
1270
+ private final TransactionTemplate txTemplate ;
1258
1271
1259
- DefaultExecutableQuery (PreparedQuery <T > preparedQuery ) {
1272
+ DefaultExecutableQuery (PreparedQuery <T > preparedQuery , boolean readOnly ) {
1260
1273
this .preparedQuery = preparedQuery ;
1274
+ this .txTemplate = readOnly ? transactionTemplateReadOnly : transactionTemplate ;
1261
1275
}
1262
1276
1277
+
1263
1278
@ SuppressWarnings ("unchecked" )
1264
1279
public List <T > getResults () {
1265
- return transactionTemplate
1280
+ return txTemplate
1266
1281
.execute (tx -> {
1267
1282
Collection <T > all = createFetchSpec ().map (Neo4jClient .RecordFetchSpec ::all ).orElse (Collections .emptyList ());
1268
1283
if (preparedQuery .resultsHaveBeenAggregated ()) {
@@ -1274,7 +1289,7 @@ public List<T> getResults() {
1274
1289
1275
1290
@ SuppressWarnings ("unchecked" )
1276
1291
public Optional <T > getSingleResult () {
1277
- return transactionTemplate .execute (tx -> {
1292
+ return txTemplate .execute (tx -> {
1278
1293
try {
1279
1294
Optional <T > one = createFetchSpec ().flatMap (Neo4jClient .RecordFetchSpec ::one );
1280
1295
if (preparedQuery .resultsHaveBeenAggregated ()) {
@@ -1291,7 +1306,7 @@ public Optional<T> getSingleResult() {
1291
1306
1292
1307
@ SuppressWarnings ("unchecked" )
1293
1308
public T getRequiredSingleResult () {
1294
- return transactionTemplate .execute (tx -> {
1309
+ return txTemplate .execute (tx -> {
1295
1310
Optional <T > one = createFetchSpec ().flatMap (Neo4jClient .RecordFetchSpec ::one );
1296
1311
if (preparedQuery .resultsHaveBeenAggregated ()) {
1297
1312
one = one .map (aggregatedResults -> ((LinkedHashSet <T >) aggregatedResults ).iterator ().next ());
0 commit comments