From 18174a8e9ef0a01d91b0c05a3e7a38c05d35ef13 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 13 Feb 2019 14:38:17 +0000 Subject: [PATCH] Polish "Add opt-in support for Neo4j-OGM native types" See gh-15637 --- .../neo4j/Neo4jDataAutoConfiguration.java | 50 ++--------------- .../data/neo4j/Neo4jProperties.java | 7 +-- .../Neo4jDataAutoConfigurationTests.java | 54 +++++++++---------- .../appendix/application-properties.adoc | 1 + .../main/asciidoc/spring-boot-features.adoc | 17 +++--- 5 files changed, 41 insertions(+), 88 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.java index ccf0c99b9f2..620dbfb0d38 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2018 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. @@ -20,9 +20,6 @@ import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.neo4j.ogm.driver.NativeTypesException; -import org.neo4j.ogm.driver.NativeTypesNotAvailableException; -import org.neo4j.ogm.driver.NativeTypesNotSupportedException; import org.neo4j.ogm.session.SessionFactory; import org.neo4j.ogm.session.event.EventListener; @@ -37,14 +34,12 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplicat import org.springframework.boot.autoconfigure.domain.EntityScanPackages; import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.data.neo4j.transaction.Neo4jTransactionManager; import org.springframework.data.neo4j.web.support.OpenSessionInViewInterceptor; -import org.springframework.lang.Nullable; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.util.StringUtils; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; @@ -58,7 +53,6 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; * @author Vince Bickers * @author Stephane Nicoll * @author Kazuki Shimizu - * @author Michael Simons * @since 1.4.0 */ @Configuration @@ -79,44 +73,10 @@ public class Neo4jDataAutoConfiguration { public SessionFactory sessionFactory(org.neo4j.ogm.config.Configuration configuration, ApplicationContext applicationContext, ObjectProvider eventListeners) { - try { - SessionFactory sessionFactory = new SessionFactory(configuration, - getPackagesToScan(applicationContext)); - eventListeners.forEach(sessionFactory::register); - return sessionFactory; - } - catch (NativeTypesException ex) { - InvalidConfigurationPropertyValueException translatedMessage = translateNativeTypesException( - ex); - throw (translatedMessage != null) ? translatedMessage : ex; - } - } - - @Nullable - private static InvalidConfigurationPropertyValueException translateNativeTypesException( - NativeTypesException cause) { - - String propertyName = Neo4jProperties.CONFIGURATION_PREFIX + ".use-native-types"; - boolean propertyValue = true; - - if (cause instanceof NativeTypesNotAvailableException) { - String message = String.format( - "The native type module for your Neo4j-OGM driver is not available. " - + "Please add the following dependency to your build:%n'%s'.", - ((NativeTypesNotAvailableException) cause).getRequiredModule()); - return new InvalidConfigurationPropertyValueException(propertyName, - propertyValue, message); - } - if (cause instanceof NativeTypesNotSupportedException) { - String message = String.format( - "The configured Neo4j-OGM driver %s does not support Neo4j native types. " - + "Please consider one of the drivers that support Neo4js native types like the Bolt or the embedded driver.", - cause.getDriverClassName()); - return new InvalidConfigurationPropertyValueException(propertyName, - propertyValue, message); - } - - return null; + SessionFactory sessionFactory = new SessionFactory(configuration, + getPackagesToScan(applicationContext)); + eventListeners.stream().forEach(sessionFactory::register); + return sessionFactory; } @Bean 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 48408be3867..9e36e5b7345 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 @@ -36,11 +36,9 @@ import org.springframework.util.ClassUtils; * @author Michael Simons * @since 1.4.0 */ -@ConfigurationProperties(prefix = Neo4jProperties.CONFIGURATION_PREFIX) +@ConfigurationProperties(prefix = "spring.data.neo4j") public class Neo4jProperties implements ApplicationContextAware { - static final String CONFIGURATION_PREFIX = "spring.data.neo4j"; - static final String EMBEDDED_DRIVER = "org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver"; static final String HTTP_DRIVER = "org.neo4j.ogm.drivers.http.driver.HttpDriver"; @@ -76,8 +74,7 @@ public class Neo4jProperties implements ApplicationContextAware { private Boolean openInView; /** - * Disables the conversion of java.time.* and spatial types in Neo4j-OGM entities and - * uses Neo4j native types wherever possible. + * Whether to use Neo4j native types wherever possible. */ private boolean useNativeTypes = false; 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 43a67c7409f..3455a4cc88f 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 @@ -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; @@ -32,7 +34,6 @@ import org.springframework.boot.autoconfigure.data.neo4j.city.City; import org.springframework.boot.autoconfigure.data.neo4j.country.Country; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; -import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; @@ -47,7 +48,6 @@ import org.springframework.data.neo4j.web.support.OpenSessionInViewInterceptor; import org.springframework.web.context.WebApplicationContext; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -158,35 +158,33 @@ public class Neo4jDataAutoConfigurationTests { } @Test - public void shouldDealWithNativeTypesNotAvailableException() { - assertThatIllegalStateException().isThrownBy(() -> { - 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) -> context.getBean(SessionFactory.class)); - }).withRootCauseInstanceOf(InvalidConfigurationPropertyValueException.class) - .withStackTraceContaining( - "The native type module for your Neo4j-OGM driver is not available. Please add the following dependency to your build:"); + 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 shouldDealWithNativeTypesNotSupportedException() { - assertThatIllegalStateException().isThrownBy(() -> { - 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) -> context.getBean(SessionFactory.class)); - }).withRootCauseInstanceOf(InvalidConfigurationPropertyValueException.class) - .withStackTraceContaining( - " The configured Neo4j-OGM driver org.neo4j.ogm.drivers.http.driver.HttpDriver does not support Neo4j native types."); + 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 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 29fea794fb1..ade50020089 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 d36069ae00a..4d85bdf27b5 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 @@ -4441,22 +4441,19 @@ 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 `java.time.*` to `String` based properties or -use one of the various native types that Neo4j provides. -For backwards compatibility reasons the default for Neo4j-OGM is using a `String` based representation. -To change that behaviour, please add one of `org.neo4j:neo4j-ogm-bolt-native-types` or `org.neo4j:neo4j-ogm-embedded-native-types` -to the dependencies of your application -and use the following property in your Spring Boot configuration: +==== 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 ---- -Please refer to the Neo4j-OGM reference for more information about -https://neo4j.com/docs/ogm-manual/current/reference/#reference:native-property-types[native property types]. - [[boot-features-neo4j-ogm-session]]