Skip to content

Commit 9666d50

Browse files
GH-2594 - Add withNeo4jConversions to both Neo4jClient and
`ReactiveNeo4jClient`. Closes #2594.
1 parent 402c0ba commit 9666d50

File tree

6 files changed

+88
-2
lines changed

6 files changed

+88
-2
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ final class DefaultNeo4jClient implements Neo4jClient {
8080
this.userSelectionProvider = builder.userSelectionProvider;
8181

8282
this.conversionService = new DefaultConversionService();
83-
new Neo4jConversions().registerConvertersIn((ConverterRegistry) conversionService);
83+
Optional.ofNullable(builder.neo4jConversions).orElseGet(Neo4jConversions::new).registerConvertersIn((ConverterRegistry) conversionService);
8484
}
8585

8686
@Override

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import java.util.Collections;
4646
import java.util.HashSet;
4747
import java.util.Map;
48+
import java.util.Optional;
4849
import java.util.Set;
4950
import java.util.concurrent.locks.ReentrantReadWriteLock;
5051
import java.util.function.BiConsumer;
@@ -81,7 +82,7 @@ final class DefaultReactiveNeo4jClient implements ReactiveNeo4jClient {
8182
this.userSelectionProvider = builder.impersonatedUserProvider;
8283

8384
this.conversionService = new DefaultConversionService();
84-
new Neo4jConversions().registerConvertersIn((ConverterRegistry) conversionService);
85+
Optional.ofNullable(builder.neo4jConversions).orElseGet(Neo4jConversions::new).registerConvertersIn((ConverterRegistry) conversionService);
8586
}
8687

8788
@Override

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.neo4j.driver.summary.ResultSummary;
3131
import org.neo4j.driver.types.TypeSystem;
3232
import org.springframework.core.log.LogAccessor;
33+
import org.springframework.data.neo4j.core.convert.Neo4jConversions;
3334
import org.springframework.lang.Nullable;
3435

3536
/**
@@ -75,6 +76,9 @@ class Builder {
7576
@Nullable
7677
UserSelectionProvider userSelectionProvider;
7778

79+
@Nullable
80+
Neo4jConversions neo4jConversions;
81+
7882
private Builder(Driver driver) {
7983
this.driver = driver;
8084
}
@@ -105,6 +109,18 @@ public Builder withUserSelectionProvider(@Nullable UserSelectionProvider userSel
105109
return this;
106110
}
107111

112+
/**
113+
* Configures the set of {@link Neo4jConversions} to use.
114+
*
115+
* @param neo4jConversions the set of conversions to use, can be {@literal null}, in this case the default set is used.
116+
* @return The builder
117+
* @since 6.3.3
118+
*/
119+
public Builder withNeo4jConversions(Neo4jConversions neo4jConversions) {
120+
this.neo4jConversions = neo4jConversions;
121+
return this;
122+
}
123+
108124
public Neo4jClient build() {
109125
return new DefaultNeo4jClient(this);
110126
}

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.neo4j.driver.types.TypeSystem;
3333
import org.springframework.core.log.LogAccessor;
3434
import org.springframework.data.neo4j.core.Neo4jClient.BindSpec;
35+
import org.springframework.data.neo4j.core.convert.Neo4jConversions;
3536
import org.springframework.lang.Nullable;
3637

3738
/**
@@ -78,6 +79,9 @@ class Builder {
7879
@Nullable
7980
ReactiveUserSelectionProvider impersonatedUserProvider;
8081

82+
@Nullable
83+
Neo4jConversions neo4jConversions;
84+
8185
private Builder(Driver driver) {
8286
this.driver = driver;
8387
}
@@ -108,6 +112,18 @@ public Builder withUserSelectionProvider(@Nullable ReactiveUserSelectionProvider
108112
return this;
109113
}
110114

115+
/**
116+
* Configures the set of {@link Neo4jConversions} to use.
117+
*
118+
* @param neo4jConversions the set of conversions to use, can be {@literal null}, in this case the default set is used.
119+
* @return The builder
120+
* @since 6.3.3
121+
*/
122+
public Builder withNeo4jConversions(Neo4jConversions neo4jConversions) {
123+
this.neo4jConversions = neo4jConversions;
124+
return this;
125+
}
126+
111127
public ReactiveNeo4jClient build() {
112128
return new DefaultReactiveNeo4jClient(this);
113129
}

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,17 @@
4545
import org.neo4j.driver.Session;
4646
import org.neo4j.driver.Value;
4747
import org.neo4j.driver.Values;
48+
import org.springframework.beans.factory.ObjectProvider;
4849
import org.springframework.beans.factory.annotation.Autowired;
4950
import org.springframework.context.annotation.Bean;
5051
import org.springframework.context.annotation.Configuration;
5152
import org.springframework.core.convert.ConversionService;
5253
import org.springframework.core.convert.support.DefaultConversionService;
5354
import org.springframework.data.mapping.MappingException;
5455
import org.springframework.data.neo4j.core.DatabaseSelectionProvider;
56+
import org.springframework.data.neo4j.core.Neo4jClient;
5557
import org.springframework.data.neo4j.core.Neo4jTemplate;
58+
import org.springframework.data.neo4j.core.UserSelectionProvider;
5659
import org.springframework.data.neo4j.core.convert.Neo4jConversions;
5760
import org.springframework.data.neo4j.core.transaction.Neo4jBookmarkManager;
5861
import org.springframework.data.neo4j.core.transaction.Neo4jTransactionManager;
@@ -276,6 +279,14 @@ void nonExistingPrimitivesShouldNotFailWithFieldAccess(@Autowired Neo4jTemplate
276279
});
277280
}
278281

282+
@Test // GH-2594
283+
void clientShouldUseCustomType(@Autowired Neo4jClient client) {
284+
285+
Optional<ThingWithCustomTypes.CustomType> value = client.query("RETURN 'whatever'")
286+
.fetchAs(ThingWithCustomTypes.CustomType.class).first();
287+
assertThat(value).map(ThingWithCustomTypes.CustomType::getValue).hasValue("whatever");
288+
}
289+
279290
public interface ConvertedIDsRepository extends Neo4jRepository<ThingWithUUIDID, UUID> {
280291
}
281292

@@ -298,6 +309,9 @@ public interface CustomTypesRepository extends Neo4jRepository<ThingWithCustomTy
298309
@EnableTransactionManagement
299310
static class Config extends Neo4jImperativeTestConfiguration {
300311

312+
@Autowired
313+
private ObjectProvider<UserSelectionProvider> userSelectionProviders;
314+
301315
@Bean
302316
public Driver driver() {
303317
return neo4jConnectionSupport.getDriver();
@@ -308,6 +322,16 @@ public Neo4jConversions neo4jConversions() {
308322
return new Neo4jConversions(Collections.singleton(new ThingWithCustomTypes.CustomTypeConverter()));
309323
}
310324

325+
@Override
326+
public Neo4jClient neo4jClient(Driver driver, DatabaseSelectionProvider databaseSelectionProvider) {
327+
328+
return Neo4jClient.with(driver)
329+
.withDatabaseSelectionProvider(databaseSelectionProvider)
330+
.withUserSelectionProvider(userSelectionProviders.getIfUnique())
331+
.withNeo4jConversions(neo4jConversions())
332+
.build();
333+
}
334+
311335
@Bean
312336
public BookmarkCapture bookmarkCapture() {
313337
return Neo4jConversionsITBase.bookmarkCapture;

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717

1818
import static org.assertj.core.api.Assertions.assertThat;
1919

20+
import org.springframework.beans.factory.ObjectProvider;
21+
import org.springframework.data.neo4j.core.ReactiveDatabaseSelectionProvider;
22+
import org.springframework.data.neo4j.core.ReactiveNeo4jClient;
23+
import org.springframework.data.neo4j.core.ReactiveUserSelectionProvider;
2024
import org.springframework.data.neo4j.test.Neo4jReactiveTestConfiguration;
2125
import reactor.core.publisher.Flux;
2226
import reactor.test.StepVerifier;
@@ -79,13 +83,28 @@ void relatedIdsShouldBeConverted(@Autowired ConvertedIDsRepository repository) {
7983
.expectNextCount(2L).verifyComplete();
8084
}
8185

86+
@Test // GH-2594
87+
void clientShouldUseCustomType(@Autowired ReactiveNeo4jClient client) {
88+
89+
client.query("RETURN 'whatever'")
90+
.fetchAs(ThingWithCustomTypes.CustomType.class)
91+
.first()
92+
.map(ThingWithCustomTypes.CustomType::getValue)
93+
.as(StepVerifier::create)
94+
.expectNext("whatever")
95+
.verifyComplete();
96+
}
97+
8298
public interface ConvertedIDsRepository extends ReactiveNeo4jRepository<ThingWithUUIDID, UUID> {}
8399

84100
@Configuration
85101
@EnableReactiveNeo4jRepositories(considerNestedRepositories = true)
86102
@EnableTransactionManagement
87103
static class Config extends Neo4jReactiveTestConfiguration {
88104

105+
@Autowired
106+
private ObjectProvider<ReactiveUserSelectionProvider> userSelectionProviders;
107+
89108
@Bean
90109
public Driver driver() {
91110
return neo4jConnectionSupport.getDriver();
@@ -100,5 +119,15 @@ public Neo4jConversions neo4jConversions() {
100119
public boolean isCypher5Compatible() {
101120
return neo4jConnectionSupport.isCypher5SyntaxCompatible();
102121
}
122+
123+
@Override
124+
public ReactiveNeo4jClient neo4jClient(Driver driver, ReactiveDatabaseSelectionProvider databaseSelectionProvider) {
125+
126+
return ReactiveNeo4jClient.with(driver)
127+
.withDatabaseSelectionProvider(databaseSelectionProvider)
128+
.withUserSelectionProvider(userSelectionProviders.getIfUnique())
129+
.withNeo4jConversions(neo4jConversions())
130+
.build();
131+
}
103132
}
104133
}

0 commit comments

Comments
 (0)