diff --git a/spring-boot-project/spring-boot-autoconfigure/pom.xml b/spring-boot-project/spring-boot-autoconfigure/pom.xml index 497e4d8188..b81e317cc7 100755 --- a/spring-boot-project/spring-boot-autoconfigure/pom.xml +++ b/spring-boot-project/spring-boot-autoconfigure/pom.xml @@ -782,7 +782,7 @@ org.neo4j - neo4j-ogm-http-driver + neo4j-ogm-bolt-native-types test @@ -790,6 +790,11 @@ neo4j-ogm-embedded-driver test + + org.neo4j + neo4j-ogm-http-driver + test + org.springframework spring-test diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jProperties.java index d1f8f8fecd..9e36e5b734 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,7 @@ import org.springframework.util.ClassUtils; * @author Michael Hunger * @author Vince Bickers * @author Aurélien Leboulanger + * @author Michael Simons * @since 1.4.0 */ @ConfigurationProperties(prefix = "spring.data.neo4j") @@ -72,6 +73,11 @@ public class Neo4jProperties implements ApplicationContextAware { */ private Boolean openInView; + /** + * Whether to use Neo4j native types wherever possible. + */ + private boolean useNativeTypes = false; + private final Embedded embedded = new Embedded(); private ClassLoader classLoader = Neo4jProperties.class.getClassLoader(); @@ -116,6 +122,14 @@ public class Neo4jProperties implements ApplicationContextAware { this.openInView = openInView; } + public boolean isUseNativeTypes() { + return this.useNativeTypes; + } + + public void setUseNativeTypes(boolean useNativeTypes) { + this.useNativeTypes = useNativeTypes; + } + public Embedded getEmbedded() { return this.embedded; } @@ -146,6 +160,9 @@ public class Neo4jProperties implements ApplicationContextAware { builder.credentials(this.username, this.password); } builder.autoIndex(this.getAutoIndex().getName()); + if (this.useNativeTypes) { + builder.useNativeTypes(); + } } private void configureUriWithDefaults(Builder builder) { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfigurationTests.java index 44ac066639..3455a4cc88 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,8 @@ package org.springframework.boot.autoconfigure.data.neo4j; import com.github.benmanes.caffeine.cache.Caffeine; import org.junit.Test; +import org.neo4j.ogm.driver.NativeTypesNotAvailableException; +import org.neo4j.ogm.driver.NativeTypesNotSupportedException; import org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver; import org.neo4j.ogm.session.Session; import org.neo4j.ogm.session.SessionFactory; @@ -51,8 +53,8 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; /** - * Tests for {@link Neo4jDataAutoConfiguration}. Tests can't use the embedded driver as we - * use Lucene 4 and Neo4j still requires 3. + * Tests for {@link Neo4jDataAutoConfiguration}. Tests should not use the embedded driver + * as it requires the complete Neo4j-Kernel and server to function properly. * * @author Stephane Nicoll * @author Michael Hunger @@ -116,7 +118,6 @@ public class Neo4jDataAutoConfigurationTests { assertThat(context) .hasSingleBean(org.neo4j.ogm.config.Configuration.class); }); - } @Test @@ -144,6 +145,48 @@ public class Neo4jDataAutoConfigurationTests { .doesNotHaveBean(OpenSessionInViewInterceptor.class)); } + @Test + public void shouldBeAbleToUseNativeTypesWithBolt() { + this.contextRunner + .withPropertyValues("spring.data.neo4j.uri=bolt://localhost:7687", + "spring.data.neo4j.use-native-types:true") + .withConfiguration(AutoConfigurations.of(Neo4jDataAutoConfiguration.class, + TransactionAutoConfiguration.class)) + .run((context) -> assertThat(context) + .getBean(org.neo4j.ogm.config.Configuration.class) + .hasFieldOrPropertyWithValue("useNativeTypes", true)); + } + + @Test + public void shouldFailWhenNativeTypesAreNotAvailable() { + this.contextRunner + .withClassLoader( + new FilteredClassLoader("org.neo4j.ogm.drivers.bolt.types")) + .withPropertyValues("spring.data.neo4j.uri=bolt://localhost:7687", + "spring.data.neo4j.use-native-types:true") + .withConfiguration(AutoConfigurations.of(Neo4jDataAutoConfiguration.class, + TransactionAutoConfiguration.class)) + .run((context) -> { + assertThat(context).hasFailed(); + assertThat(context.getStartupFailure()).hasRootCauseInstanceOf( + NativeTypesNotAvailableException.class); + }); + } + + @Test + public void shouldFailWhenNativeTypesAreNotSupported() { + this.contextRunner + .withPropertyValues("spring.data.neo4j.uri=http://localhost:7474", + "spring.data.neo4j.use-native-types:true") + .withConfiguration(AutoConfigurations.of(Neo4jDataAutoConfiguration.class, + TransactionAutoConfiguration.class)) + .run((context) -> { + assertThat(context).hasFailed(); + assertThat(context.getStartupFailure()).hasRootCauseInstanceOf( + NativeTypesNotSupportedException.class); + }); + } + @Test public void eventListenersAreAutoRegistered() { this.contextRunner.withUserConfiguration(EventListenerConfiguration.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jPropertiesTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jPropertiesTests.java index 827b574194..2fbb627739 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jPropertiesTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jPropertiesTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,6 +35,7 @@ import static org.assertj.core.api.Assertions.assertThat; * Tests for {@link Neo4jProperties}. * * @author Stephane Nicoll + * @author Michael Simons */ public class Neo4jPropertiesTests { @@ -147,6 +148,21 @@ public class Neo4jPropertiesTests { "file:relative/path/to/my.db"); } + @Test + public void nativeTypesAreSetToFalseByDefault() { + Neo4jProperties properties = load(true); + Configuration configuration = properties.createConfiguration(); + assertThat(configuration.getUseNativeTypes()).isFalse(); + } + + @Test + public void nativeTypesCanBeConfigured() { + Neo4jProperties properties = load(true, + "spring.data.neo4j.use-native-types=true"); + Configuration configuration = properties.createConfiguration(); + assertThat(configuration.getUseNativeTypes()).isTrue(); + } + private static void assertDriver(Configuration actual, String driver, String uri) { assertThat(actual).isNotNull(); assertThat(actual.getDriverClassName()).isEqualTo(driver); diff --git a/spring-boot-project/spring-boot-dependencies/pom.xml b/spring-boot-project/spring-boot-dependencies/pom.xml index 450b917e2c..7caf4a42aa 100644 --- a/spring-boot-project/spring-boot-dependencies/pom.xml +++ b/spring-boot-project/spring-boot-dependencies/pom.xml @@ -2527,6 +2527,11 @@ neo4j-ogm-bolt-driver ${neo4j-ogm.version} + + org.neo4j + neo4j-ogm-bolt-native-types + ${neo4j-ogm.version} + org.neo4j neo4j-ogm-core @@ -2537,6 +2542,11 @@ neo4j-ogm-embedded-driver ${neo4j-ogm.version} + + org.neo4j + neo4j-ogm-embedded-native-types + ${neo4j-ogm.version} + org.neo4j neo4j-ogm-http-driver diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix/application-properties.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix/application-properties.adoc index 29fea794fb..ade5002008 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix/application-properties.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix/application-properties.adoc @@ -695,6 +695,7 @@ content into your application. Rather, pick only the properties that you need. spring.data.neo4j.password= # Login password of the server. spring.data.neo4j.repositories.enabled=true # Whether to enable Neo4j repositories. spring.data.neo4j.uri= # URI used by the driver. Auto-detected by default. + spring.data.neo4j.use-native-types=false # Whether to use Neo4j native types wherever possible. spring.data.neo4j.username= # Login user of the server. # DATA REST ({sc-spring-boot-autoconfigure}/data/rest/RepositoryRestProperties.{sc-ext}[RepositoryRestProperties]) diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index 4aaf614cd6..4d85bdf27b 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc @@ -4440,6 +4440,22 @@ in your configuration, e.g. `spring.data.neo4j.uri=file://var/tmp/graph.db`. +[[boot-features-neo4j-ogm-native-types]] +==== Using Native Types +Neo4j-OGM can map some types, like those in `java.time.*`, to `String`-based properties +or to one of the native types that Neo4j provides. For backwards compatibility reasons +the default for Neo4j-OGM is to use a `String`-based representation. To use native types, +add a dependency on either `org.neo4j:neo4j-ogm-bolt-native-types` or +`org.neo4j:neo4j-ogm-embedded-native-types`, and configure the +`spring.data.neo4j.use-native-types` property as shown in the following example: + +[source,properties,indent=0] +---- + spring.data.neo4j.use-native-types=true +---- + + + [[boot-features-neo4j-ogm-session]] ==== Neo4jSession By default, if you are running a web application, the session is bound to the thread for