Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 7d65de1

Browse files
michael-simonsmeistermeier
authored andcommitted
refactor: Upgrade to Driver 6, and test against last Neo4j 5.26 LTS release by default.
Signed-off-by: Michael Simons <michael@simons.ac>
1 parent a87f748 commit 7d65de1

File tree

10 files changed

+102
-109
lines changed

10 files changed

+102
-109
lines changed

‎pom.xml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@
9797
<maven-install-plugin.version>3.1.4</maven-install-plugin.version>
9898
<maven-site-plugin.version>3.7.1</maven-site-plugin.version>
9999
<maven.compiler.release>${java.version}</maven.compiler.release>
100-
<neo4j-java-driver.version>5.28.9</neo4j-java-driver.version>
100+
<neo4j-java-driver.version>6.0.0</neo4j-java-driver.version>
101101
<neo4j-migrations.version>2.17.3</neo4j-migrations.version>
102102
<neo4j.version>5.26.12</neo4j.version>
103103
<objenesis.version>3.0.1</objenesis.version>

‎src/main/java/org/springframework/data/neo4j/core/ResultSummaries.java‎

Lines changed: 43 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.springframework.data.neo4j.core;
1717

18+
import java.util.List;
1819
import java.util.function.Consumer;
1920
import java.util.function.Predicate;
2021
import java.util.regex.Pattern;
@@ -23,10 +24,9 @@
2324

2425
import org.apache.commons.logging.LogFactory;
2526
import org.jspecify.annotations.Nullable;
26-
import org.neo4j.driver.NotificationCategory;
27+
import org.neo4j.driver.NotificationClassification;
2728
import org.neo4j.driver.NotificationSeverity;
28-
import org.neo4j.driver.summary.InputPosition;
29-
import org.neo4j.driver.summary.Notification;
29+
import org.neo4j.driver.summary.GqlNotification;
3030
import org.neo4j.driver.summary.Plan;
3131
import org.neo4j.driver.summary.ResultSummary;
3232

@@ -66,8 +66,15 @@ final class ResultSummaries {
6666
private static final LogAccessor cypherTopologyNotificationLog = new LogAccessor(
6767
LogFactory.getLog("org.springframework.data.neo4j.cypher.topology"));
6868

69-
private static final Pattern DEPRECATED_ID_PATTERN = Pattern
70-
.compile("(?im)The query used a deprecated function[.:] \\(?[`']id.+");
69+
private static final LogAccessor cypherSchemaNotificationLog = new LogAccessor(
70+
LogFactory.getLog("org.springframework.data.neo4j.cypher.schema"));
71+
72+
private static final List<Pattern> STUFF_THAT_MIGHT_INFORM_THAT_THE_ID_FUNCTION_IS_PROBLEMATIC = Stream.of(
73+
"(?im)The query used a deprecated function[.:] \\(?[`']id.+",
74+
"(?im).*id is deprecated and will be removed without a replacement\\.",
75+
"(?im).*feature deprecated with replacement\\. id is deprecated\\. It is replaced by elementId or consider using an application-generated id\\.")
76+
.map(Pattern::compile)
77+
.toList();
7178

7279
private ResultSummaries() {
7380
}
@@ -86,29 +93,33 @@ static ResultSummary process(ResultSummary resultSummary) {
8693

8794
private static void logNotifications(ResultSummary resultSummary) {
8895

89-
if (resultSummary.notifications().isEmpty() || !Neo4jClient.cypherLog.isWarnEnabled()) {
96+
if (resultSummary.gqlStatusObjects().isEmpty() || !Neo4jClient.cypherLog.isWarnEnabled()) {
9097
return;
9198
}
9299

93100
boolean supressIdDeprecations = Neo4jClient.SUPPRESS_ID_DEPRECATIONS.getAcquire();
94-
Predicate<Notification> isDeprecationWarningForId;
101+
Predicate<GqlNotification> isDeprecationWarningForId;
95102
try {
96103
isDeprecationWarningForId = notification -> supressIdDeprecations
97-
&& notification.category()
98-
.orElse(NotificationCategory.UNRECOGNIZED)
99-
.equals(NotificationCategory.DEPRECATION)
100-
&& DEPRECATED_ID_PATTERN.matcher(notification.description()).matches();
104+
&& notification.classification()
105+
.filter(cat -> cat == NotificationClassification.UNRECOGNIZED
106+
|| cat == NotificationClassification.DEPRECATION)
107+
.isPresent()
108+
&& STUFF_THAT_MIGHT_INFORM_THAT_THE_ID_FUNCTION_IS_PROBLEMATIC.stream()
109+
.anyMatch(p -> p.matcher(notification.statusDescription()).matches());
101110
}
102111
finally {
103112
Neo4jClient.SUPPRESS_ID_DEPRECATIONS.setRelease(supressIdDeprecations);
104113
}
105114

106115
String query = resultSummary.query().text();
107-
resultSummary.notifications()
116+
resultSummary.gqlStatusObjects()
108117
.stream()
118+
.filter(GqlNotification.class::isInstance)
119+
.map(GqlNotification.class::cast)
109120
.filter(Predicate.not(isDeprecationWarningForId))
110-
.forEach(notification -> notification.severityLevel().ifPresent(severityLevel -> {
111-
var category = notification.category().orElse(null);
121+
.forEach(notification -> notification.severity().ifPresent(severityLevel -> {
122+
var category = notification.classification().orElse(null);
112123

113124
var logger = getLogAccessor(category);
114125
Consumer<String> logFunction;
@@ -130,35 +141,22 @@ else if (severityLevel == NotificationSeverity.OFF) {
130141
}));
131142
}
132143

133-
private static LogAccessor getLogAccessor(@Nullable NotificationCategorycategory) {
134-
if (category == null) {
144+
private static LogAccessor getLogAccessor(@Nullable NotificationClassificationclassification) {
145+
if (classification == null) {
135146
return Neo4jClient.cypherLog;
136147
}
137-
if (category.equals(NotificationCategory.HINT)) {
138-
return cypherHintNotificationLog;
139-
}
140-
else if (category.equals(NotificationCategory.DEPRECATION)) {
141-
return cypherDeprecationNotificationLog;
142-
}
143-
else if (category.equals(NotificationCategory.PERFORMANCE)) {
144-
return cypherPerformanceNotificationLog;
145-
}
146-
else if (category.equals(NotificationCategory.GENERIC)) {
147-
return cypherGenericNotificationLog;
148-
}
149-
else if (category.equals(NotificationCategory.UNSUPPORTED)) {
150-
return cypherUnsupportedNotificationLog;
151-
}
152-
else if (category.equals(NotificationCategory.UNRECOGNIZED)) {
153-
return cypherUnrecognizedNotificationLog;
154-
}
155-
else if (category.equals(NotificationCategory.SECURITY)) {
156-
return cypherSecurityNotificationLog;
157-
}
158-
else if (category.equals(NotificationCategory.TOPOLOGY)) {
159-
return cypherTopologyNotificationLog;
160-
}
161-
return Neo4jClient.cypherLog;
148+
149+
return switch (classification) {
150+
case HINT -> cypherHintNotificationLog;
151+
case UNRECOGNIZED -> cypherUnrecognizedNotificationLog;
152+
case UNSUPPORTED -> cypherUnsupportedNotificationLog;
153+
case PERFORMANCE -> cypherPerformanceNotificationLog;
154+
case DEPRECATION -> cypherDeprecationNotificationLog;
155+
case SECURITY -> cypherSecurityNotificationLog;
156+
case TOPOLOGY -> cypherTopologyNotificationLog;
157+
case GENERIC -> cypherGenericNotificationLog;
158+
case SCHEMA -> cypherSchemaNotificationLog;
159+
};
162160
}
163161

164162
/**
@@ -167,25 +165,23 @@ else if (category.equals(NotificationCategory.TOPOLOGY)) {
167165
* @param forQuery the query that caused the notification
168166
* @return a formatted string
169167
*/
170-
static String format(Notification notification, String forQuery) {
168+
static String format(GqlNotification notification, String forQuery) {
171169

172-
InputPosition position = notification.position();
173-
boolean hasPosition = position != null;
170+
var position = notification.position().orElse(null);
174171

175172
StringBuilder queryHint = new StringBuilder();
176173
String[] lines = forQuery.split("(\r\n|\n)");
177174
for (int i = 0; i < lines.length; i++) {
178175
String line = lines[i];
179176
queryHint.append("\t").append(line).append(LINE_SEPARATOR);
180-
if (hasPosition && i + 1 == position.line()) {
177+
if (position != null && i + 1 == position.line()) {
181178
queryHint.append("\t")
182179
.append(Stream.generate(() -> " ").limit(position.column() - 1).collect(Collectors.joining()))
183180
.append("^")
184181
.append(System.lineSeparator());
185182
}
186183
}
187-
return String.format("%s: %s%n%s%s", notification.code(), notification.title(), queryHint,
188-
notification.description());
184+
return String.format("%s (%s):%n%s", notification.statusDescription(), notification.gqlStatus(), queryHint);
189185
}
190186

191187
/**

‎src/main/java/org/springframework/data/neo4j/repository/query/AbstractNeo4jQuery.java‎

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import java.util.function.LongSupplier;
2424
import java.util.function.Supplier;
2525
import java.util.function.UnaryOperator;
26-
import java.util.stream.Collectors;
2726

2827
import org.jspecify.annotations.Nullable;
2928
import org.neo4j.driver.types.MapAccessor;
@@ -166,7 +165,7 @@ else if (geoNearQuery) {
166165
rawResult = newGeoResults(rawResult);
167166
}
168167
else if (this.queryMethod.isSearchQuery()) {
169-
rawResult = createSearchResult((List<?>) rawResult, returnedType.getReturnedType());
168+
rawResult = createSearchResult((List<?>) rawResult);
170169
}
171170

172171
return resultProcessor.processResult(rawResult, preparingConverter);
@@ -207,11 +206,9 @@ private Slice<?> createSlice(boolean incrementLimit, Neo4jParameterAccessor para
207206
}
208207
}
209208

210-
private <T> SearchResults<?> createSearchResult(List<?> rawResult, Class<T> returnedType) {
211-
List<SearchResult<T>> searchResults = rawResult.stream()
212-
.map(rawValue -> (SearchResult<T>) rawValue)
213-
.collect(Collectors.toUnmodifiableList());
214-
return new SearchResults<>(searchResults);
209+
@SuppressWarnings("unchecked")
210+
private <T> SearchResults<?> createSearchResult(List<?> rawResult) {
211+
return new SearchResults<>(rawResult.stream().map(rawValue -> (SearchResult<T>) rawValue).toList());
215212
}
216213

217214
protected abstract <T> PreparedQuery<T> prepareQuery(Class<T> returnedType,

‎src/test/java/org/springframework/data/neo4j/core/Neo4jClientTests.java‎

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ void databaseSelectionShouldWorkBeforeAsUser() {
141141
verify(this.session).run(eq(cypher), MockitoHamcrest.argThat(new MapAssertionMatcher(expectedParameters)));
142142
verify(this.result).stream();
143143
verify(this.result).consume();
144-
verify(this.resultSummary).notifications();
144+
verify(this.resultSummary).gqlStatusObjects();
145145
verify(this.resultSummary).hasPlan();
146146
verify(this.record1).asMap();
147147
verify(this.session).close();
@@ -181,7 +181,7 @@ void databaseSelectionShouldWorkAfterAsUser() {
181181
verify(this.session).run(eq(cypher), MockitoHamcrest.argThat(new MapAssertionMatcher(expectedParameters)));
182182
verify(this.result).stream();
183183
verify(this.result).consume();
184-
verify(this.resultSummary).notifications();
184+
verify(this.resultSummary).gqlStatusObjects();
185185
verify(this.resultSummary).hasPlan();
186186
verify(this.record1).asMap();
187187
verify(this.session).close();
@@ -220,7 +220,7 @@ void userSelectionShouldWork() {
220220
verify(this.session).run(eq(cypher), MockitoHamcrest.argThat(new MapAssertionMatcher(expectedParameters)));
221221
verify(this.result).stream();
222222
verify(this.result).consume();
223-
verify(this.resultSummary).notifications();
223+
verify(this.resultSummary).gqlStatusObjects();
224224
verify(this.resultSummary).hasPlan();
225225
verify(this.record1).asMap();
226226
verify(this.session).close();
@@ -268,7 +268,7 @@ void queryCreationShouldFeelGood() {
268268

269269
verify(this.result).stream();
270270
verify(this.result).consume();
271-
verify(this.resultSummary).notifications();
271+
verify(this.resultSummary).gqlStatusObjects();
272272
verify(this.resultSummary).hasPlan();
273273
verify(this.record1).asMap();
274274
verify(this.record2).asMap();
@@ -305,7 +305,7 @@ void databaseSelectionShouldBePossibleOnlyOnce() {
305305
verify(this.session).run(eq(cypher), MockitoHamcrest.argThat(new MapAssertionMatcher(expectedParameters)));
306306
verify(this.result).stream();
307307
verify(this.result).consume();
308-
verify(this.resultSummary).notifications();
308+
verify(this.resultSummary).gqlStatusObjects();
309309
verify(this.resultSummary).hasPlan();
310310
verify(this.record1).asMap();
311311
verify(this.session).close();
@@ -350,7 +350,7 @@ void databaseSelectionBeanShouldGetRespectedIfExisting() {
350350
verify(this.session).run(eq(query), anyMap());
351351
verify(this.result).stream();
352352
verify(this.result).consume();
353-
verify(this.resultSummary).notifications();
353+
verify(this.resultSummary).gqlStatusObjects();
354354
verify(this.resultSummary).hasPlan();
355355
verify(this.record1).asMap();
356356
verify(this.session).close();
@@ -379,7 +379,7 @@ void queriesWithoutResultShouldFitInAsWell() {
379379

380380
verify(this.session).run(eq(cypher), MockitoHamcrest.argThat(new MapAssertionMatcher(expectedParameters)));
381381
verify(this.result).consume();
382-
verify(this.resultSummary).notifications();
382+
verify(this.resultSummary).gqlStatusObjects();
383383
verify(this.resultSummary).hasPlan();
384384
verify(this.session).close();
385385
}
@@ -577,7 +577,7 @@ void reading() {
577577
MockitoHamcrest.argThat(new MapAssertionMatcher(expectedParameters)));
578578
verify(Neo4jClientTests.this.result).stream();
579579
verify(Neo4jClientTests.this.result).consume();
580-
verify(Neo4jClientTests.this.resultSummary).notifications();
580+
verify(Neo4jClientTests.this.resultSummary).gqlStatusObjects();
581581
verify(Neo4jClientTests.this.resultSummary).hasPlan();
582582
verify(Neo4jClientTests.this.record1).get("name");
583583
verify(Neo4jClientTests.this.session).close();
@@ -614,7 +614,7 @@ void shouldApplyNullChecksDuringReading() {
614614
MockitoHamcrest.argThat(new MapAssertionMatcher(Collections.emptyMap())));
615615
verify(Neo4jClientTests.this.result).stream();
616616
verify(Neo4jClientTests.this.result).consume();
617-
verify(Neo4jClientTests.this.resultSummary).notifications();
617+
verify(Neo4jClientTests.this.resultSummary).gqlStatusObjects();
618618
verify(Neo4jClientTests.this.resultSummary).hasPlan();
619619
verify(Neo4jClientTests.this.record1).get("name");
620620
verify(Neo4jClientTests.this.session).close();
@@ -646,7 +646,7 @@ void writing() {
646646
verify(Neo4jClientTests.this.session).run(eq(cypher),
647647
MockitoHamcrest.argThat(new MapAssertionMatcher(expectedParameters)));
648648
verify(Neo4jClientTests.this.result).consume();
649-
verify(Neo4jClientTests.this.resultSummary).notifications();
649+
verify(Neo4jClientTests.this.resultSummary).gqlStatusObjects();
650650
verify(Neo4jClientTests.this.resultSummary).hasPlan();
651651
verify(Neo4jClientTests.this.session).close();
652652
}
@@ -677,7 +677,7 @@ void automaticConversion() {
677677
verify(Neo4jClientTests.this.result).hasNext();
678678
verify(Neo4jClientTests.this.result).single();
679679
verify(Neo4jClientTests.this.result).consume();
680-
verify(Neo4jClientTests.this.resultSummary).notifications();
680+
verify(Neo4jClientTests.this.resultSummary).gqlStatusObjects();
681681
verify(Neo4jClientTests.this.resultSummary).hasPlan();
682682
verify(Neo4jClientTests.this.session).close();
683683
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /