Skip to content

Commit 0e055f9

Browse files
committed
GH-2531 - Add Neo4j 5.0 Cypher support.
This provides also the support for defining a CypherDSL configuration bean.
1 parent 4a81fae commit 0e055f9

File tree

92 files changed

+732
-186
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

92 files changed

+732
-186
lines changed

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
<byte-buddy.version>1.11.0</byte-buddy.version>
7676
<cdi>2.0.SP1</cdi>
7777
<checkstyle.version>8.40</checkstyle.version>
78-
<cypher-dsl.version>2022.2.0</cypher-dsl.version>
78+
<cypher-dsl.version>2022.3.0</cypher-dsl.version>
7979
<dist.id>spring-data-neo4j</dist.id>
8080
<dist.key>SDNEO4J</dist.key>
8181
<flatten-maven-plugin.version>1.2.5</flatten-maven-plugin.version>

src/main/java/org/springframework/data/neo4j/config/Neo4jCdiConfigurationSupport.java

+12-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
package org.springframework.data.neo4j.config;
1717

1818
import org.apiguardian.api.API;
19+
import org.neo4j.cypherdsl.core.renderer.Configuration;
20+
import org.neo4j.cypherdsl.core.renderer.Renderer;
1921
import org.neo4j.driver.Driver;
2022
import org.springframework.data.neo4j.core.DatabaseSelectionProvider;
2123
import org.springframework.data.neo4j.core.Neo4jClient;
@@ -63,12 +65,20 @@ public DatabaseSelectionProvider databaseSelectionProvider() {
6365
return DatabaseSelectionProvider.getDefaultSelectionProvider();
6466
}
6567

68+
@Produces @Builtin @Singleton
69+
public Configuration cypherDslConfiguration() {
70+
return Configuration.defaultConfig();
71+
}
72+
6673
@Produces @Builtin @Singleton
6774
public Neo4jOperations neo4jOperations(
6875
@Any Instance<Neo4jClient> neo4jClient,
69-
@Any Instance<Neo4jMappingContext> mappingContext
76+
@Any Instance<Neo4jMappingContext> mappingContext,
77+
@Any Instance<Configuration> cypherDslConfiguration
7078
) {
71-
return new Neo4jTemplate(resolve(neo4jClient), resolve(mappingContext));
79+
Neo4jTemplate neo4jTemplate = new Neo4jTemplate(resolve(neo4jClient), resolve(mappingContext));
80+
neo4jTemplate.setCypherRenderer(Renderer.getRenderer(resolve(cypherDslConfiguration)));
81+
return neo4jTemplate;
7282
}
7383

7484
@Produces @Singleton

src/main/java/org/springframework/data/neo4j/config/Neo4jConfigurationSupport.java

+6
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.Set;
2121

2222
import org.apiguardian.api.API;
23+
import org.neo4j.cypherdsl.core.renderer.Configuration;
2324
import org.springframework.context.annotation.Bean;
2425
import org.springframework.data.neo4j.core.convert.Neo4jConversions;
2526
import org.springframework.data.neo4j.core.mapping.Neo4jMappingContext;
@@ -42,6 +43,11 @@ public Neo4jConversions neo4jConversions() {
4243
return new Neo4jConversions();
4344
}
4445

46+
@Bean
47+
public Configuration cypherDslConfiguration() {
48+
return Configuration.defaultConfig();
49+
}
50+
4551
/**
4652
* Creates a {@link Neo4jMappingContext} equipped with entity classes scanned from the mapping base package.
4753
*

src/main/java/org/springframework/data/neo4j/core/Neo4jTemplate.java

+13-2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import org.neo4j.cypherdsl.core.Functions;
4646
import org.neo4j.cypherdsl.core.Node;
4747
import org.neo4j.cypherdsl.core.Statement;
48+
import org.neo4j.cypherdsl.core.renderer.Configuration;
4849
import org.neo4j.cypherdsl.core.renderer.Renderer;
4950
import org.neo4j.driver.Value;
5051
import org.neo4j.driver.exceptions.NoSuchRecordException;
@@ -110,8 +111,6 @@ public final class Neo4jTemplate implements
110111

111112
private static final String OPTIMISTIC_LOCKING_ERROR_MESSAGE = "An entity with the required version does not exist.";
112113

113-
private static final Renderer renderer = Renderer.getDefaultRenderer();
114-
115114
private final Neo4jClient neo4jClient;
116115

117116
private final Neo4jMappingContext neo4jMappingContext;
@@ -124,6 +123,8 @@ public final class Neo4jTemplate implements
124123

125124
private ProjectionFactory projectionFactory;
126125

126+
private Renderer renderer;
127+
127128
@Deprecated
128129
public Neo4jTemplate(Neo4jClient neo4jClient, Neo4jMappingContext neo4jMappingContext,
129130
DatabaseSelectionProvider databaseSelectionProvider) {
@@ -927,6 +928,16 @@ public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
927928
spelAwareProxyProjectionFactory.setBeanClassLoader(beanClassLoader);
928929
spelAwareProxyProjectionFactory.setBeanFactory(beanFactory);
929930
this.projectionFactory = spelAwareProxyProjectionFactory;
931+
932+
Configuration cypherDslConfiguration = beanFactory
933+
.getBeanProvider(Configuration.class)
934+
.getIfAvailable(Configuration::defaultConfig);
935+
this.renderer = Renderer.getRenderer(cypherDslConfiguration);
936+
}
937+
938+
// only used for the CDI configuration
939+
public void setCypherRenderer(Renderer rendererFromCdiConfiguration) {
940+
this.renderer = rendererFromCdiConfiguration;
930941
}
931942

932943
@Override

src/main/java/org/springframework/data/neo4j/core/ReactiveNeo4jTemplate.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static org.neo4j.cypherdsl.core.Cypher.asterisk;
2020
import static org.neo4j.cypherdsl.core.Cypher.parameter;
2121

22+
import org.neo4j.cypherdsl.core.renderer.Configuration;
2223
import org.springframework.data.mapping.Association;
2324
import org.springframework.data.neo4j.core.TemplateSupport.FilteredBinderFunction;
2425
import org.springframework.data.neo4j.core.mapping.AssociationHandlerSupport;
@@ -113,7 +114,6 @@ public final class ReactiveNeo4jTemplate implements
113114

114115
private static final String OPTIMISTIC_LOCKING_ERROR_MESSAGE = "An entity with the required version does not exist.";
115116

116-
private static final Renderer renderer = Renderer.getDefaultRenderer();
117117
private static final String CONTEXT_RELATIONSHIP_HANDLER = "RELATIONSHIP_HANDLER";
118118

119119
private final ReactiveNeo4jClient neo4jClient;
@@ -128,6 +128,8 @@ public final class ReactiveNeo4jTemplate implements
128128

129129
private ProjectionFactory projectionFactory;
130130

131+
private Renderer renderer;
132+
131133
@Deprecated
132134
public ReactiveNeo4jTemplate(ReactiveNeo4jClient neo4jClient, Neo4jMappingContext neo4jMappingContext,
133135
ReactiveDatabaseSelectionProvider databaseSelectionProvider) {
@@ -1124,6 +1126,11 @@ public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
11241126
spelAwareProxyProjectionFactory.setBeanClassLoader(beanClassLoader);
11251127
spelAwareProxyProjectionFactory.setBeanFactory(beanFactory);
11261128
this.projectionFactory = spelAwareProxyProjectionFactory;
1129+
1130+
Configuration cypherDslConfiguration = beanFactory
1131+
.getBeanProvider(Configuration.class)
1132+
.getIfAvailable(Configuration::defaultConfig);
1133+
this.renderer = Renderer.getRenderer(cypherDslConfiguration);
11271134
}
11281135

11291136
@Override

src/main/java/org/springframework/data/neo4j/core/mapping/CypherGenerator.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
import org.neo4j.cypherdsl.core.StatementBuilder.OngoingMatchAndUpdate;
5353
import org.neo4j.cypherdsl.core.StatementBuilder.OngoingUpdate;
5454
import org.neo4j.cypherdsl.core.SymbolicName;
55+
import org.neo4j.cypherdsl.core.renderer.Configuration;
5556
import org.neo4j.cypherdsl.core.renderer.Renderer;
5657
import org.springframework.data.domain.Sort;
5758
import org.springframework.data.mapping.MappingException;
@@ -511,7 +512,8 @@ public Collection<Expression> createReturnStatementForMatch(Neo4jPersistentEntit
511512
return order.isAscending() ? expression.ascending() : expression.descending();
512513
}).toArray(SortItem[]::new))
513514
.build();
514-
String renderedStatement = Renderer.getDefaultRenderer().render(statement);
515+
516+
String renderedStatement = Renderer.getRenderer(Configuration.defaultConfig()).render(statement);
515517
return renderedStatement.substring(renderedStatement.indexOf("ORDER BY")).trim();
516518
}
517519

src/test/java/org/springframework/data/neo4j/documentation/repositories/custom_queries/CustomQueriesIT.java

+7-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import org.springframework.beans.factory.annotation.Autowired;
3030
import org.springframework.context.annotation.Bean;
3131
import org.springframework.context.annotation.Configuration;
32-
import org.springframework.data.neo4j.config.AbstractNeo4jConfig;
3332
import org.springframework.data.neo4j.core.DatabaseSelectionProvider;
3433
import org.springframework.data.neo4j.core.transaction.Neo4jBookmarkManager;
3534
import org.springframework.data.neo4j.core.transaction.Neo4jTransactionManager;
@@ -40,6 +39,7 @@
4039
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
4140
import org.springframework.data.neo4j.test.BookmarkCapture;
4241
import org.springframework.data.neo4j.test.Neo4jExtension;
42+
import org.springframework.data.neo4j.test.Neo4jImperativeTestConfiguration;
4343
import org.springframework.data.neo4j.test.Neo4jIntegrationTest;
4444
import org.springframework.transaction.PlatformTransactionManager;
4545
import org.springframework.transaction.annotation.EnableTransactionManagement;
@@ -93,7 +93,7 @@ interface PersonRepository extends Neo4jRepository<PersonEntity, String> {
9393
@Configuration
9494
@EnableTransactionManagement
9595
@EnableNeo4jRepositories(considerNestedRepositories = true)
96-
static class Config extends AbstractNeo4jConfig {
96+
static class Config extends Neo4jImperativeTestConfiguration {
9797

9898
@Bean
9999
@Override
@@ -117,5 +117,10 @@ public PlatformTransactionManager transactionManager(Driver driver, DatabaseSele
117117
BookmarkCapture bookmarkCapture = bookmarkCapture();
118118
return new Neo4jTransactionManager(driver, databaseNameProvider, Neo4jBookmarkManager.create(bookmarkCapture));
119119
}
120+
121+
@Override
122+
public boolean isCypher5Compatible() {
123+
return neo4jConnectionSupport.isCypher5SyntaxCompatible();
124+
}
120125
}
121126
}

src/test/java/org/springframework/data/neo4j/integration/conversion_imperative/CustomTypesIT.java

+7-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
import org.springframework.context.annotation.Bean;
4040
import org.springframework.context.annotation.Configuration;
4141
import org.springframework.core.convert.converter.GenericConverter;
42-
import org.springframework.data.neo4j.config.AbstractNeo4jConfig;
42+
import org.springframework.data.neo4j.test.Neo4jImperativeTestConfiguration;
4343
import org.springframework.data.neo4j.core.DatabaseSelectionProvider;
4444
import org.springframework.data.neo4j.core.Neo4jOperations;
4545
import org.springframework.data.neo4j.core.convert.Neo4jConversions;
@@ -239,7 +239,7 @@ ThingWithCustomTypes findByCustomTypeSpELObjectQuery(
239239
@Configuration
240240
@EnableTransactionManagement
241241
@EnableNeo4jRepositories(considerNestedRepositories = true)
242-
static class Config extends AbstractNeo4jConfig {
242+
static class Config extends Neo4jImperativeTestConfiguration {
243243

244244
@Bean
245245
@Override
@@ -274,5 +274,10 @@ public PlatformTransactionManager transactionManager(Driver driver, DatabaseSele
274274
BookmarkCapture bookmarkCapture = bookmarkCapture();
275275
return new Neo4jTransactionManager(driver, databaseNameProvider, Neo4jBookmarkManager.create(bookmarkCapture));
276276
}
277+
278+
@Override
279+
public boolean isCypher5Compatible() {
280+
return neo4jConnectionSupport.isCypher5SyntaxCompatible();
281+
}
277282
}
278283
}

src/test/java/org/springframework/data/neo4j/integration/conversion_imperative/ImperativeCompositePropertiesIT.java

+7-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import org.springframework.beans.factory.annotation.Autowired;
2828
import org.springframework.context.annotation.Bean;
2929
import org.springframework.context.annotation.Configuration;
30-
import org.springframework.data.neo4j.config.AbstractNeo4jConfig;
3130
import org.springframework.data.neo4j.core.DatabaseSelectionProvider;
3231
import org.springframework.data.neo4j.core.Neo4jTemplate;
3332
import org.springframework.data.neo4j.core.convert.Neo4jConversions;
@@ -40,6 +39,7 @@
4039
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
4140
import org.springframework.data.neo4j.test.BookmarkCapture;
4241
import org.springframework.data.neo4j.test.Neo4jExtension;
42+
import org.springframework.data.neo4j.test.Neo4jImperativeTestConfiguration;
4343
import org.springframework.data.neo4j.test.Neo4jIntegrationTest;
4444
import org.springframework.transaction.PlatformTransactionManager;
4545
import org.springframework.transaction.annotation.EnableTransactionManagement;
@@ -141,7 +141,7 @@ public interface Repository extends Neo4jRepository<ThingWithCompositeProperties
141141
@Configuration
142142
@EnableNeo4jRepositories(considerNestedRepositories = true)
143143
@EnableTransactionManagement
144-
static class Config extends AbstractNeo4jConfig {
144+
static class Config extends Neo4jImperativeTestConfiguration {
145145

146146
@Bean
147147
public Driver driver() {
@@ -164,5 +164,10 @@ public PlatformTransactionManager transactionManager(Driver driver, DatabaseSele
164164
BookmarkCapture bookmarkCapture = bookmarkCapture();
165165
return new Neo4jTransactionManager(driver, databaseNameProvider, Neo4jBookmarkManager.create(bookmarkCapture));
166166
}
167+
168+
@Override
169+
public boolean isCypher5Compatible() {
170+
return neo4jConnectionSupport.isCypher5SyntaxCompatible();
171+
}
167172
}
168173
}

src/test/java/org/springframework/data/neo4j/integration/conversion_imperative/TypeConversionIT.java

+7-2
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
import org.springframework.core.convert.ConversionService;
5252
import org.springframework.core.convert.support.DefaultConversionService;
5353
import org.springframework.data.mapping.MappingException;
54-
import org.springframework.data.neo4j.config.AbstractNeo4jConfig;
5554
import org.springframework.data.neo4j.core.DatabaseSelectionProvider;
5655
import org.springframework.data.neo4j.core.Neo4jTemplate;
5756
import org.springframework.data.neo4j.core.convert.Neo4jConversions;
@@ -68,6 +67,7 @@
6867
import org.springframework.data.neo4j.repository.Neo4jRepository;
6968
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
7069
import org.springframework.data.neo4j.test.BookmarkCapture;
70+
import org.springframework.data.neo4j.test.Neo4jImperativeTestConfiguration;
7171
import org.springframework.data.neo4j.test.Neo4jIntegrationTest;
7272
import org.springframework.test.util.ReflectionTestUtils;
7373
import org.springframework.transaction.PlatformTransactionManager;
@@ -297,7 +297,7 @@ public interface CustomTypesRepository extends Neo4jRepository<ThingWithCustomTy
297297
@Configuration
298298
@EnableNeo4jRepositories(considerNestedRepositories = true)
299299
@EnableTransactionManagement
300-
static class Config extends AbstractNeo4jConfig {
300+
static class Config extends Neo4jImperativeTestConfiguration {
301301

302302
@Bean
303303
public Driver driver() {
@@ -320,5 +320,10 @@ public PlatformTransactionManager transactionManager(Driver driver, DatabaseSele
320320
BookmarkCapture bookmarkCapture = bookmarkCapture();
321321
return new Neo4jTransactionManager(driver, databaseNameProvider, Neo4jBookmarkManager.create(bookmarkCapture));
322322
}
323+
324+
@Override
325+
public boolean isCypher5Compatible() {
326+
return neo4jConnectionSupport.isCypher5SyntaxCompatible();
327+
}
323328
}
324329
}

src/test/java/org/springframework/data/neo4j/integration/conversion_reactive/ReactiveCompositePropertiesIT.java

+7-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.springframework.data.neo4j.core.transaction.Neo4jBookmarkManager;
2727
import org.springframework.data.neo4j.core.transaction.ReactiveNeo4jTransactionManager;
2828
import org.springframework.data.neo4j.integration.shared.conversion.ThingWithCustomTypes;
29+
import org.springframework.data.neo4j.test.Neo4jReactiveTestConfiguration;
2930
import reactor.test.StepVerifier;
3031

3132
import java.util.ArrayList;
@@ -38,7 +39,6 @@
3839
import org.springframework.beans.factory.annotation.Autowired;
3940
import org.springframework.context.annotation.Bean;
4041
import org.springframework.context.annotation.Configuration;
41-
import org.springframework.data.neo4j.config.AbstractReactiveNeo4jConfig;
4242
import org.springframework.data.neo4j.integration.shared.conversion.CompositePropertiesITBase;
4343
import org.springframework.data.neo4j.integration.shared.conversion.ThingWithCompositeProperties;
4444
import org.springframework.data.neo4j.repository.ReactiveNeo4jRepository;
@@ -150,7 +150,7 @@ public interface Repository extends ReactiveNeo4jRepository<ThingWithCompositePr
150150
@Configuration
151151
@EnableReactiveNeo4jRepositories(considerNestedRepositories = true)
152152
@EnableTransactionManagement
153-
static class Config extends AbstractReactiveNeo4jConfig {
153+
static class Config extends Neo4jReactiveTestConfiguration {
154154

155155
@Bean
156156
public Driver driver() {
@@ -173,5 +173,10 @@ public ReactiveTransactionManager reactiveTransactionManager(Driver driver, Reac
173173
BookmarkCapture bookmarkCapture = bookmarkCapture();
174174
return new ReactiveNeo4jTransactionManager(driver, databaseSelectionProvider, Neo4jBookmarkManager.create(bookmarkCapture));
175175
}
176+
177+
@Override
178+
public boolean isCypher5Compatible() {
179+
return neo4jConnectionSupport.isCypher5SyntaxCompatible();
180+
}
176181
}
177182
}

src/test/java/org/springframework/data/neo4j/integration/conversion_reactive/ReactiveCustomTypesIT.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.springframework.data.neo4j.core.transaction.Neo4jBookmarkManager;
2222
import org.springframework.data.neo4j.core.transaction.ReactiveNeo4jTransactionManager;
2323
import org.springframework.data.neo4j.test.BookmarkCapture;
24+
import org.springframework.data.neo4j.test.Neo4jReactiveTestConfiguration;
2425
import org.springframework.transaction.ReactiveTransactionManager;
2526
import reactor.core.publisher.Mono;
2627
import reactor.test.StepVerifier;
@@ -47,7 +48,6 @@
4748
import org.springframework.context.annotation.Bean;
4849
import org.springframework.context.annotation.Configuration;
4950
import org.springframework.core.convert.converter.GenericConverter;
50-
import org.springframework.data.neo4j.config.AbstractReactiveNeo4jConfig;
5151
import org.springframework.data.neo4j.core.ReactiveNeo4jOperations;
5252
import org.springframework.data.neo4j.core.convert.Neo4jConversions;
5353
import org.springframework.data.neo4j.integration.shared.conversion.PersonWithCustomId;
@@ -190,7 +190,7 @@ Mono<ThingWithCustomTypes> findByCustomTypeSpELObjectQuery(
190190
@Configuration
191191
@EnableReactiveNeo4jRepositories(considerNestedRepositories = true)
192192
@EnableTransactionManagement
193-
static class Config extends AbstractReactiveNeo4jConfig {
193+
static class Config extends Neo4jReactiveTestConfiguration {
194194

195195
@Bean
196196
public Driver driver() {
@@ -224,5 +224,9 @@ public ReactiveTransactionManager reactiveTransactionManager(Driver driver, Reac
224224
return new ReactiveNeo4jTransactionManager(driver, databaseSelectionProvider, Neo4jBookmarkManager.create(bookmarkCapture));
225225
}
226226

227+
@Override
228+
public boolean isCypher5Compatible() {
229+
return neo4jConnectionSupport.isCypher5SyntaxCompatible();
230+
}
227231
}
228232
}

0 commit comments

Comments
 (0)