diff --git a/spring-boot-actuator/pom.xml b/spring-boot-actuator/pom.xml
index d4c7b547e5..cf323298cb 100644
--- a/spring-boot-actuator/pom.xml
+++ b/spring-boot-actuator/pom.xml
@@ -166,6 +166,11 @@
spring-data-mongodb
true
+
+ org.springframework.data
+ spring-data-neo4j
+ true
+
org.springframework.data
spring-data-redis
diff --git a/spring-boot-autoconfigure/pom.xml b/spring-boot-autoconfigure/pom.xml
index 9951e96cb1..b6de2d4b7b 100755
--- a/spring-boot-autoconfigure/pom.xml
+++ b/spring-boot-autoconfigure/pom.xml
@@ -379,6 +379,17 @@
+
+ org.springframework.data
+ spring-data-neo4j
+ true
+
+
+ jcl-over-slf4j
+ org.slf4j
+
+
+
org.springframework.data
spring-data-redis
@@ -635,5 +646,6 @@
tomcat-embed-jasper
test
+
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfiguration.java
index 1afa03ff98..7a8630d260 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfiguration.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfiguration.java
@@ -53,8 +53,7 @@ import org.springframework.data.mongodb.repository.support.MongoRepositoryFactor
*/
@Configuration
@ConditionalOnClass({ Mongo.class, MongoRepository.class })
-@ConditionalOnMissingBean({ MongoRepositoryFactoryBean.class,
- MongoRepositoryConfigurationExtension.class })
+@ConditionalOnMissingBean({ MongoRepositoryFactoryBean.class, MongoRepositoryConfigurationExtension.class })
@ConditionalOnProperty(prefix = "spring.data.mongodb.repositories", name = "enabled", havingValue = "true", matchIfMissing = true)
@Import(MongoRepositoriesAutoConfigureRegistrar.class)
@AutoConfigureAfter(MongoDataAutoConfiguration.class)
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jAutoConfiguration.java
new file mode 100644
index 0000000000..b5b9b69f1b
--- /dev/null
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jAutoConfiguration.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2012-2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.autoconfigure.data.neo4j;
+
+import org.neo4j.ogm.session.Neo4jSession;
+import org.neo4j.ogm.session.Session;
+import org.neo4j.ogm.session.SessionFactory;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Scope;
+import org.springframework.context.annotation.ScopedProxyMode;
+
+import org.springframework.data.neo4j.config.Neo4jConfiguration;
+import org.springframework.data.neo4j.template.Neo4jOperations;
+import org.springframework.data.neo4j.template.Neo4jTemplate;
+
+/**
+ * {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Neo4j support.
+ *
+ * Registers a {@link Neo4jTemplate} bean if no other bean of
+ * the same type is configured.
+ *
+ * @author Michael Hunger
+ * @author Josh Long
+ * @author Vince Bickers
+ * @since 1.3.0
+ */
+@Configuration
+@EnableConfigurationProperties(Neo4jProperties.class)
+@ConditionalOnMissingBean(type = "org.springframework.data.neo4j.template.Neo4jOperations")
+@ConditionalOnClass({ Neo4jSession.class, Neo4jOperations.class })
+public class Neo4jAutoConfiguration extends Neo4jConfiguration {
+
+ @Autowired
+ private Neo4jProperties properties;
+
+ @Value("${spring.data.neo4j.domain.packages:null}")
+ private String[] domainPackages;
+
+ @Bean
+ @ConditionalOnMissingBean(org.neo4j.ogm.config.Configuration.class)
+ public org.neo4j.ogm.config.Configuration configuration() {
+ return this.properties.configure();
+ }
+
+ @Override
+ @ConditionalOnMissingBean(SessionFactory.class)
+ public SessionFactory getSessionFactory() {
+ return new SessionFactory(configuration(), this.domainPackages);
+ }
+
+ @Bean
+ @ConditionalOnMissingBean(Session.class)
+ @Scope(value = "${spring.data.neo4j.session.lifetime:session}", proxyMode = ScopedProxyMode.TARGET_CLASS)
+ public Session getSession() throws Exception {
+ return getSessionFactory().openSession();
+ }
+
+}
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jProperties.java
new file mode 100644
index 0000000000..73b3974883
--- /dev/null
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jProperties.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2012-2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.autoconfigure.data.neo4j;
+
+import org.neo4j.ogm.config.Configuration;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * Configuration properties for Neo4j.
+ *
+ * @author Dave Syer
+ * @author Phillip Webb
+ * @author Josh Long
+ * @author Andy Wilkinson
+ * @author EddĂș MelĂ©ndez
+ * @author Michael Hunger
+ * @author Vince Bickers
+ */
+@ConfigurationProperties(prefix = "spring.data.neo4j")
+public class Neo4jProperties {
+
+ // if you don't set this up somewhere, this is what we'll use by default
+ private String driver = "org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver";
+ private String compiler;
+ private String URI;
+ private String username;
+ private String password;
+
+ public String getDriver() {
+ return this.driver;
+ }
+
+ public void setDriver(String driver) {
+ this.driver = driver;
+ }
+
+ public String getCompiler() {
+ return this.compiler;
+ }
+
+ public void setCompiler(String compiler) {
+ this.compiler = compiler;
+ }
+
+ public String getURI() {
+ return this.URI;
+ }
+
+ public void setURI(String URI) {
+ this.URI = URI;
+ }
+
+ public String getUsername() {
+ return this.username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return this.password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public Configuration configure() {
+ Configuration configuration = new Configuration();
+
+ if (this.driver != null) {
+ configuration.driverConfiguration().setDriverClassName(this.driver);
+ }
+
+ if (this.URI != null) {
+ configuration.driverConfiguration().setURI(this.URI);
+ }
+
+ if (this.username != null && this.password != null) {
+ configuration.driverConfiguration().setCredentials(this.username, this.password);
+ }
+
+ if (this.compiler != null) {
+ configuration.compilerConfiguration().setCompilerClassName(this.compiler);
+ }
+
+ return configuration;
+ }
+}
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfiguration.java
new file mode 100644
index 0000000000..2cc223d8c7
--- /dev/null
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfiguration.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2012-2014 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.autoconfigure.data.neo4j;
+
+import org.neo4j.ogm.session.Neo4jSession;
+
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+import org.springframework.data.neo4j.repository.GraphRepository;
+
+import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
+import org.springframework.data.neo4j.repository.config.Neo4jRepositoryConfigurationExtension;
+import org.springframework.data.neo4j.repository.support.GraphRepositoryFactoryBean;
+
+/**
+ * {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Neo4j
+ * Repositories.
+ *
+ * Activates when there is no bean of type
+ * {@link org.springframework.data.neo4j.repository.support.GraphRepositoryFactoryBean}
+ * configured in the context, the Spring Data Neo4j
+ * {@link org.springframework.data.neo4j.repository.GraphRepository} type is on the
+ * classpath, the Neo4j client driver API is on the classpath, and there is no other
+ * configured {@link org.springframework.data.neo4j.repository.GraphRepository}.
+ *
+ * Once in effect, the auto-configuration is the equivalent of enabling Neo4j repositories
+ * using the
+ * {@link org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories}
+ * annotation.
+ *
+ * @author Dave Syer
+ * @author Oliver Gierke
+ * @author Josh Long
+ * @see EnableNeo4jRepositories
+ */
+@Configuration
+@ConditionalOnClass({ Neo4jSession.class, GraphRepository.class })
+@ConditionalOnMissingBean({ GraphRepositoryFactoryBean.class, Neo4jRepositoryConfigurationExtension.class })
+@ConditionalOnProperty(prefix = "spring.data.neo4j.repositories", name = "enabled", havingValue = "true", matchIfMissing = true)
+@Import({Neo4jRepositoriesAutoConfigureRegistrar.class})
+@AutoConfigureAfter(Neo4jAutoConfiguration.class)
+public class Neo4jRepositoriesAutoConfiguration {
+
+}
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfigureRegistrar.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfigureRegistrar.java
new file mode 100644
index 0000000000..1651010535
--- /dev/null
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfigureRegistrar.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2012-2014 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.autoconfigure.data.neo4j;
+
+import java.lang.annotation.Annotation;
+
+import org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport;
+import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
+import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
+import org.springframework.data.neo4j.repository.config.Neo4jRepositoryConfigurationExtension;
+import org.springframework.data.repository.config.RepositoryConfigurationExtension;
+
+/**
+ * {@link ImportBeanDefinitionRegistrar} used to auto-configure Spring Data Neo4j
+ * Repositories.
+ *
+ * @author Dave Syer
+ */
+class Neo4jRepositoriesAutoConfigureRegistrar extends
+ AbstractRepositoryConfigurationSourceSupport {
+
+ @Override
+ protected Class extends Annotation> getAnnotation() {
+ return EnableNeo4jRepositories.class;
+ }
+
+ @Override
+ protected Class> getConfiguration() {
+ return EnableNeo4jRepositoriesConfiguration.class;
+ }
+
+ @Override
+ protected RepositoryConfigurationExtension getRepositoryConfigurationExtension() {
+ return new Neo4jRepositoryConfigurationExtension();
+ }
+
+ @EnableNeo4jRepositories
+ private static class EnableNeo4jRepositoriesConfiguration {
+ }
+
+}
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/package-info.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/package-info.java
new file mode 100644
index 0000000000..a681b2a7d5
--- /dev/null
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2012-2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Auto-configuration for Spring Data Neo4j.
+ */
+package org.springframework.boot.autoconfigure.data.neo4j;
+
diff --git a/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json
index fba5f4e02c..6b720f28ab 100644
--- a/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json
+++ b/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json
@@ -90,6 +90,12 @@
"description": "Enable Mongo repositories.",
"defaultValue": true
},
+ {
+ "name": "spring.data.neo4j.repositories.enabled",
+ "type": "java.lang.Boolean",
+ "description": "Enable Neo4j repositories.",
+ "defaultValue": true
+ },
{
"name": "spring.data.redis.repositories.enabled",
"type": "java.lang.Boolean",
diff --git a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories
index 811f7d78f3..90463d5960 100644
--- a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories
+++ b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories
@@ -31,6 +31,8 @@ org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositor
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
+org.springframework.boot.autoconfigure.data.neo4j.Neo4jAutoConfiguration,\
+org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/neo4j/CityNeo4jRepository.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/neo4j/CityNeo4jRepository.java
new file mode 100644
index 0000000000..722bc7a823
--- /dev/null
+++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/neo4j/CityNeo4jRepository.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2012-2014 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.autoconfigure.data.alt.neo4j;
+
+import org.springframework.boot.autoconfigure.data.neo4j.city.City;
+import org.springframework.data.neo4j.repository.GraphRepository;
+
+public interface CityNeo4jRepository extends GraphRepository {
+}
diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/MixedNeo4jRepositoriesAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/MixedNeo4jRepositoriesAutoConfigurationTests.java
new file mode 100644
index 0000000000..6741bb0cb5
--- /dev/null
+++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/MixedNeo4jRepositoriesAutoConfigurationTests.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2012-2014 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.autoconfigure.data.neo4j;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.assertj.core.api.Assertions;
+
+import org.junit.After;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
+import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration;
+import org.springframework.boot.autoconfigure.data.jpa.city.City;
+import org.springframework.boot.autoconfigure.data.jpa.city.CityRepository;
+import org.springframework.boot.autoconfigure.data.neo4j.country.Country;
+import org.springframework.boot.autoconfigure.data.neo4j.country.CountryRepository;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfigurationTests;
+import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
+
+import org.springframework.boot.orm.jpa.EntityScan;
+
+import org.springframework.boot.test.EnvironmentTestUtils;
+
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.context.annotation.ImportSelector;
+
+import org.springframework.core.type.AnnotationMetadata;
+
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+
+import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
+
+/**
+ * Tests for {@link org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration}.
+ *
+ * @author Dave Syer
+ * @author Oliver Gierke
+ * @author Michael Hunger
+ * @author Vince Bickers
+ */
+public class MixedNeo4jRepositoriesAutoConfigurationTests {
+
+ private AnnotationConfigApplicationContext context;
+
+ @After
+ public void close() {
+ this.context.close();
+ }
+
+ @Test
+ public void testDefaultRepositoryConfiguration() throws Exception {
+ this.context = new AnnotationConfigApplicationContext();
+ EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.initialize:false");
+ this.context.register(TestConfiguration.class, BaseConfiguration.class);
+ this.context.refresh();
+ Assertions.assertThat(this.context.getBean(CountryRepository.class)).isNotNull();
+ }
+
+ @Test
+ public void testMixedRepositoryConfiguration() throws Exception {
+ this.context = new AnnotationConfigApplicationContext();
+ EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.initialize:false");
+ this.context.register(MixedConfiguration.class, BaseConfiguration.class);
+ this.context.refresh();
+ Assertions.assertThat(this.context.getBean(CountryRepository.class)).isNotNull();
+ Assertions.assertThat(this.context.getBean(CityRepository.class)).isNotNull();
+ }
+
+ @Test
+ public void testJpaRepositoryConfigurationWithNeo4jTemplate() throws Exception {
+ this.context = new AnnotationConfigApplicationContext();
+ EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.initialize:false");
+ this.context.register(JpaConfiguration.class, BaseConfiguration.class);
+ this.context.refresh();
+ Assertions.assertThat(this.context.getBean(CityRepository.class)).isNotNull();
+ }
+
+ @Test
+ @Ignore
+ public void testJpaRepositoryConfigurationWithNeo4jOverlap() throws Exception {
+ this.context = new AnnotationConfigApplicationContext();
+ EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.initialize:false");
+ this.context.register(OverlapConfiguration.class, BaseConfiguration.class);
+ this.context.refresh();
+ Assertions.assertThat(this.context.getBean(CityRepository.class)).isNotNull();
+ }
+
+ @Test
+ public void testJpaRepositoryConfigurationWithNeo4jOverlapDisabled() throws Exception {
+ this.context = new AnnotationConfigApplicationContext();
+ EnvironmentTestUtils.addEnvironment(this.context,
+ "spring.datasource.initialize:false",
+ "spring.data.neo4j.repositories.enabled:false");
+ this.context.register(OverlapConfiguration.class, BaseConfiguration.class);
+ this.context.refresh();
+ Assertions.assertThat(this.context.getBean(CityRepository.class)).isNotNull();
+ }
+
+ @Configuration
+ @TestAutoConfigurationPackage(Neo4jAutoConfigurationTests.class)
+ // Not this package or its parent
+ @EnableNeo4jRepositories(basePackageClasses = Country.class)
+ protected static class TestConfiguration {
+
+ }
+
+ @Configuration
+ @TestAutoConfigurationPackage(Neo4jAutoConfigurationTests.class)
+ @EnableNeo4jRepositories(basePackageClasses = Country.class)
+ @EntityScan(basePackageClasses = City.class)
+ @EnableJpaRepositories(basePackageClasses = CityRepository.class)
+ protected static class MixedConfiguration {
+
+ }
+
+ @Configuration
+ @TestAutoConfigurationPackage(Neo4jAutoConfigurationTests.class)
+ @EntityScan(basePackageClasses = City.class)
+ @EnableJpaRepositories(basePackageClasses = CityRepository.class)
+ protected static class JpaConfiguration {
+
+ }
+
+ // In this one the Jpa repositories and the autoconfiguration packages overlap, so
+ // Neo4j will try and configure the same repositories
+ @Configuration
+ @TestAutoConfigurationPackage(CityRepository.class)
+ @EnableJpaRepositories(basePackageClasses = CityRepository.class)
+ protected static class OverlapConfiguration {
+
+ }
+
+ @Configuration
+ @Import(Registrar.class)
+ protected static class BaseConfiguration {
+
+ }
+
+ protected static class Registrar implements ImportSelector {
+
+ @Override
+ public String[] selectImports(AnnotationMetadata importingClassMetadata) {
+ List names = new ArrayList();
+ for (Class> type : new Class>[] { DataSourceAutoConfiguration.class,
+ HibernateJpaAutoConfiguration.class,
+ JpaRepositoriesAutoConfiguration.class,
+ Neo4jAutoConfiguration.class,
+ Neo4jRepositoriesAutoConfiguration.class }) {
+ names.add(type.getName());
+ }
+ return names.toArray(new String[names.size()]);
+ }
+ }
+
+}
diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfigurationTests.java
new file mode 100644
index 0000000000..5afdb1d86e
--- /dev/null
+++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfigurationTests.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2012-2014 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.autoconfigure.data.neo4j;
+
+import org.assertj.core.api.Assertions;
+
+import org.junit.After;
+import org.junit.Test;
+
+import org.neo4j.ogm.session.SessionFactory;
+
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+
+import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
+import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
+import org.springframework.boot.autoconfigure.data.alt.neo4j.CityNeo4jRepository;
+import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage;
+import org.springframework.boot.autoconfigure.data.neo4j.city.City;
+import org.springframework.boot.autoconfigure.data.neo4j.city.CityRepository;
+
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.annotation.Configuration;
+
+import org.springframework.data.neo4j.mapping.Neo4jMappingContext;
+import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
+
+/**
+ * Tests for {@link org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration}.
+ *
+ * @author Dave Syer
+ * @author Oliver Gierke
+ * @author Michael Hunger
+ * @author Vince Bickers
+ */
+public class Neo4jRepositoriesAutoConfigurationTests {
+
+ private AnnotationConfigApplicationContext context;
+
+ @After
+ public void close() {
+ this.context.close();
+ }
+
+ @Test
+ public void testDefaultRepositoryConfiguration() throws Exception {
+
+ prepareApplicationContext(TestConfiguration.class);
+
+ Assertions.assertThat(this.context.getBean(CityRepository.class)).isNotNull();
+
+ Neo4jMappingContext mappingContext = this.context.getBean(Neo4jMappingContext.class);
+ Assertions.assertThat(mappingContext.getPersistentEntity(City.class)).isNotNull();
+
+ }
+
+ @Test
+ public void testNoRepositoryConfiguration() throws Exception {
+ prepareApplicationContext(EmptyConfiguration.class);
+ Assertions.assertThat(this.context.getBean(SessionFactory.class)).isNotNull();
+ }
+
+ @Test
+ public void doesNotTriggerDefaultRepositoryDetectionIfCustomized() {
+ prepareApplicationContext(CustomizedConfiguration.class);
+
+ Assertions.assertThat(this.context.getBean(CityNeo4jRepository.class)).isNotNull();
+ }
+
+ @Test(expected = NoSuchBeanDefinitionException.class)
+ public void autoConfigurationShouldNotKickInEvenIfManualConfigDidNotCreateAnyRepositories() {
+ prepareApplicationContext(SortOfInvalidCustomConfiguration.class);
+
+ this.context.getBean(CityRepository.class);
+ }
+
+ private void prepareApplicationContext(Class>... configurationClasses) {
+ this.context = new AnnotationConfigApplicationContext();
+ this.context.register(configurationClasses);
+ this.context.register(Neo4jAutoConfiguration.class,
+ Neo4jRepositoriesAutoConfiguration.class,
+ PropertyPlaceholderAutoConfiguration.class);
+ this.context.refresh();
+ }
+
+ @Configuration
+ @TestAutoConfigurationPackage(City.class)
+ protected static class TestConfiguration {
+
+ }
+
+ @Configuration
+ @TestAutoConfigurationPackage(EmptyDataPackage.class)
+ protected static class EmptyConfiguration {
+
+ }
+
+ @Configuration
+ @TestAutoConfigurationPackage(Neo4jRepositoriesAutoConfigurationTests.class)
+ @EnableNeo4jRepositories(basePackageClasses = CityNeo4jRepository.class)
+ protected static class CustomizedConfiguration {
+
+ }
+
+ @Configuration
+ // To not find any repositories
+ @EnableNeo4jRepositories("foo.bar")
+ @TestAutoConfigurationPackage(Neo4jRepositoriesAutoConfigurationTests.class)
+ protected static class SortOfInvalidCustomConfiguration {
+
+ }
+}
diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/city/City.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/city/City.java
new file mode 100644
index 0000000000..df7694538f
--- /dev/null
+++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/city/City.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2012-2013 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.autoconfigure.data.neo4j.city;
+
+import java.io.Serializable;
+
+import org.neo4j.ogm.annotation.GraphId;
+import org.neo4j.ogm.annotation.NodeEntity;
+
+import org.springframework.boot.autoconfigure.data.neo4j.country.Country;
+
+@NodeEntity
+public class City implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @GraphId
+ private Long id;
+
+ private String name;
+
+ private String state;
+
+ private Country country;
+
+ private String map;
+
+ public City() {
+ }
+
+ public City(String name, Country country) {
+ this.name = name;
+ this.country = country;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public String getState() {
+ return this.state;
+ }
+
+ public Country getCountry() {
+ return this.country;
+ }
+
+ public String getMap() {
+ return this.map;
+ }
+
+ @Override
+ public String toString() {
+ return getName() + "," + getState() + "," + getCountry();
+ }
+}
diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/city/CityRepository.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/city/CityRepository.java
new file mode 100644
index 0000000000..a89e07909f
--- /dev/null
+++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/city/CityRepository.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2012-2013 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.autoconfigure.data.neo4j.city;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.neo4j.repository.GraphRepository;
+
+public interface CityRepository extends GraphRepository {
+
+ Page findAll(Pageable pageable);
+
+// TODO: cannot resolve queries like this at the moment.
+//
+// Page findByNameLikeAndCountryLikeAllIgnoringCase(String name, String country,
+// Pageable pageable);
+//
+// City findByNameAndCountry(String name, String country);
+
+}
diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/country/Country.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/country/Country.java
new file mode 100644
index 0000000000..012ddd1e54
--- /dev/null
+++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/country/Country.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2012-2013 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.autoconfigure.data.neo4j.country;
+
+import java.io.Serializable;
+
+import org.neo4j.ogm.annotation.GraphId;
+import org.neo4j.ogm.annotation.NodeEntity;
+
+@NodeEntity
+public class Country implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @GraphId
+ private Long id;
+
+ private String name;
+
+ public Country() {
+ }
+
+ public Country(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ @Override
+ public String toString() {
+ return getName();
+ }
+}
diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/country/CountryRepository.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/country/CountryRepository.java
new file mode 100644
index 0000000000..1814c642da
--- /dev/null
+++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/country/CountryRepository.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2012-2013 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.autoconfigure.data.neo4j.country;
+
+import org.springframework.data.neo4j.repository.GraphRepository;
+
+public interface CountryRepository extends GraphRepository {
+
+}
diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/neo4j/Neo4jAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/neo4j/Neo4jAutoConfigurationTests.java
new file mode 100644
index 0000000000..d4c10bee39
--- /dev/null
+++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/neo4j/Neo4jAutoConfigurationTests.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2012-2014 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.autoconfigure.neo4j;
+
+import org.assertj.core.api.Assertions;
+
+import org.junit.After;
+import org.junit.Test;
+
+import org.neo4j.ogm.config.Configuration;
+
+import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
+import org.springframework.boot.autoconfigure.data.neo4j.Neo4jAutoConfiguration;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+/**
+ * Tests for {@link Neo4jAutoConfiguration}.
+ *
+ * @author Dave Syer
+ * @author Michael Hunger
+ * @author Vince Bickers
+ */
+public class Neo4jAutoConfigurationTests {
+
+ private AnnotationConfigApplicationContext context;
+
+ @After
+ public void close() {
+ if (this.context != null) {
+ this.context.close();
+ }
+ }
+
+ @Test
+ public void configurationExists() {
+ this.context = new AnnotationConfigApplicationContext(
+ PropertyPlaceholderAutoConfiguration.class, Neo4jAutoConfiguration.class);
+ Assertions.assertThat(this.context.getBeanNamesForType(Configuration.class).length).isEqualTo(1);
+ }
+
+}
diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/neo4j/Neo4jDataAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/neo4j/Neo4jDataAutoConfigurationTests.java
new file mode 100644
index 0000000000..8227b24f7c
--- /dev/null
+++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/neo4j/Neo4jDataAutoConfigurationTests.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2012-2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.autoconfigure.neo4j;
+
+import org.assertj.core.api.Assertions;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.junit.rules.ExpectedException;
+
+import org.neo4j.ogm.session.SessionFactory;
+
+import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
+import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
+import org.springframework.boot.autoconfigure.data.neo4j.Neo4jAutoConfiguration;
+import org.springframework.boot.autoconfigure.data.neo4j.city.City;
+
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+import org.springframework.data.neo4j.mapping.Neo4jMappingContext;
+import org.springframework.data.neo4j.template.Neo4jOperations;
+
+/**
+ * Tests for {@link Neo4jAutoConfiguration}.
+ *
+ * @author Josh Long
+ * @author Oliver Gierke
+ * @author Vince Bickers
+ */
+public class Neo4jDataAutoConfigurationTests {
+
+ @Rule
+ public final ExpectedException thrown = ExpectedException.none();
+
+ private AnnotationConfigApplicationContext context;
+
+ @After
+ public void close() {
+ if (this.context != null) {
+ this.context.close();
+ }
+ }
+
+ @Test
+ public void templateExists() {
+ this.context = new AnnotationConfigApplicationContext();
+ this.context.register(PropertyPlaceholderAutoConfiguration.class, Neo4jAutoConfiguration.class);
+ this.context.refresh();
+ Assertions.assertThat(this.context.getBeanNamesForType(Neo4jOperations.class).length).isEqualTo(1);
+ }
+
+ @Test
+ public void sessionFactoryExists() {
+ this.context = new AnnotationConfigApplicationContext();
+ this.context.register(PropertyPlaceholderAutoConfiguration.class, Neo4jAutoConfiguration.class);
+ this.context.refresh();
+ Assertions.assertThat(this.context.getBeanNamesForType(SessionFactory.class).length).isEqualTo(1);
+ }
+
+ @Test
+ public void usesAutoConfigurationPackageToPickUpDomainTypes() {
+ this.context = new AnnotationConfigApplicationContext();
+ String cityPackage = City.class.getPackage().getName();
+ AutoConfigurationPackages.register(this.context, cityPackage);
+ this.context.register(Neo4jAutoConfiguration.class);
+ this.context.refresh();
+ assertDomainTypesDiscovered(this.context.getBean(Neo4jMappingContext.class),
+ City.class);
+ }
+
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ private static void assertDomainTypesDiscovered(Neo4jMappingContext mappingContext,
+ Class>... types) {
+ for (Class> type : types) {
+ Assertions.assertThat(mappingContext.getPersistentEntity(type)).isNotNull();
+ }
+ }
+
+}
diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/neo4j/Neo4jPropertiesTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/neo4j/Neo4jPropertiesTests.java
new file mode 100644
index 0000000000..e619acbf95
--- /dev/null
+++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/neo4j/Neo4jPropertiesTests.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2012-2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.autoconfigure.neo4j;
+
+import org.assertj.core.api.Assertions;
+
+import org.junit.Test;
+
+import org.springframework.boot.autoconfigure.data.neo4j.Neo4jProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.boot.test.EnvironmentTestUtils;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Tests for {@link Neo4jProperties}.
+ *
+ * @author Phillip Webb
+ * @author Andy Wilkinson
+ * @author Vince Bickers
+ */
+
+public class Neo4jPropertiesTests {
+
+ @Test
+ public void shouldHaveCorrectDefaultDriver() {
+
+ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
+ context.register(Conf.class);
+ context.refresh();
+
+ Neo4jProperties neo4jProperties = context.getBean(Neo4jProperties.class);
+
+ Assertions.assertThat(neo4jProperties.getDriver()).isEqualTo("org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver");
+ }
+
+ @Test
+ public void shouldConfigureFromDefaults() {
+
+ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
+ context.register(Conf.class);
+ context.refresh();
+
+ Neo4jProperties neo4jProperties = context.getBean(Neo4jProperties.class);
+
+ org.neo4j.ogm.config.Configuration configuration = neo4jProperties.configure();
+ Assertions.assertThat(configuration.driverConfiguration().getDriverClassName())
+ .isEqualTo("org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver");
+
+ }
+
+ @Test
+ public void shouldBeCustomisable() {
+
+ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
+ EnvironmentTestUtils.addEnvironment(context, "spring.data.neo4j.driver:CustomDriver");
+ context.register(Conf.class);
+ context.refresh();
+
+ Neo4jProperties neo4jProperties = context.getBean(Neo4jProperties.class);
+
+ Assertions.assertThat(neo4jProperties.getDriver()).isEqualTo("CustomDriver");
+
+ }
+
+ @Configuration
+ @EnableConfigurationProperties(Neo4jProperties.class)
+ static class Conf {
+ }
+}
diff --git a/spring-boot-dependencies/pom.xml b/spring-boot-dependencies/pom.xml
index d6570f51fb..39156dd5f8 100644
--- a/spring-boot-dependencies/pom.xml
+++ b/spring-boot-dependencies/pom.xml
@@ -55,9 +55,11 @@
2.1.9
1.9.2
3.2.2
+ 1.10
1.4
2.1.1
2.1
+ 3.4
1.6
2.4.2
2.2.3
@@ -325,6 +327,11 @@
spring-boot-starter-data-redis
1.4.0.BUILD-SNAPSHOT
+
+ org.springframework.boot
+ spring-boot-starter-data-neo4j
+ 1.4.0.BUILD-SNAPSHOT
+
org.springframework.boot
spring-boot-starter-data-rest
@@ -768,11 +775,17 @@
commons-collections
${commons-collections.version}
+
+ commons-codec
+ commons-codec
+ ${commons-codec.version}
+
commons-dbcp
commons-dbcp
${commons-dbcp.version}
+
commons-digester
commons-digester
@@ -2149,6 +2162,7 @@
wsdl4j
${wsdl4j.version}
+
diff --git a/spring-boot-docs/pom.xml b/spring-boot-docs/pom.xml
index 3500b5bd58..b36c2a3d56 100644
--- a/spring-boot-docs/pom.xml
+++ b/spring-boot-docs/pom.xml
@@ -488,6 +488,11 @@
spring-data-mongodb
true
+
+ org.springframework.data
+ spring-data-neo4j
+ true
+
org.springframework.data
spring-data-redis
diff --git a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc
index 7c88a8e2e1..0568ede96b 100644
--- a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc
+++ b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc
@@ -3009,6 +3009,179 @@ Mongo instance's configuration and logging routing.
+[[boot-features-neo4j]]
+=== Neo4j
+http://neo4j.com/[Neo4j] is an open-source NoSQL graph database that uses a
+rich data model of nodes related by first class relationships which is better
+suited for connected big data than traditional rdbms approaches.
+Spring Boot offers several conveniences for working with Neo4j, including the
+`spring-boot-starter-data-neo4j` '`Starter POM`'.
+
+[[boot-features-connecting-to-neo4j]]
+==== Connecting to a Neo4j database
+You can inject an auto-configured `org.neo4j.ogm.session.Neo4jSession` to
+access Neo4j databases.
+
+In your `application properties`, you can supply any domain packages to be scanned by the OGM at startup
+as well as the lifetime of the OGM session that will be established for web clients.
+
+By default your application will be configured to use an in-process embedded instance of Neo4j that will not persist any data when your application shuts down. You can also connect to a remote Neo4j server, or to an embedded instance that persists data between restarts of your application.
+
+The following sections show how you can configure your application for each of these scenarios.
+
+[[boot-features-neo4j-embedded]]
+==== Connecting to an embedded database
+[source,properties,indent=0]
+----
+ # embedded driver (optional: default is embedded driver)
+ spring.data.neo4j.driver=org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver
+
+ # database path (optional: default is in-memory)
+ spring.data.neo4j.URI=file://var/tmp/graph.db
+
+ # declare the domain packages for the OGM to scan at startup
+ # note: if you don't need to do any object mapping, you can omit this property
+ spring.data.neo4.domain.packages=my.app.domain.core, my.app.domain.external, ...
+
+ # OGM session lifetime for web clients
+ # options: session (httpSession), request (httpRequest)
+ # default: session
+ spring.data.neo4j.session.lifetime=session
+----
+
+[[boot-features-neo4j-remote]]
+==== Connecting to a remote database
+[source,properties,indent=0]
+----
+ # http driver
+ spring.data.neo4j.driver=org.neo4j.ogm.drivers.http.driver.HttpDriver
+
+ # database uri
+ spring.data.neo4j.URI=http://user:password@localhost:7474
+
+ # declare the domain packages for the OGM to scan at startup
+ # note: if you don't need to do any object mapping, you can omit this property
+ spring.data.neo4.domain.packages=my.app.domain.core, my.app.domain.external, ...
+
+ # OGM session lifetime for web clients
+ # options: session (httpSession), request (httpRequest)
+ # default: session
+ spring.data.neo4j.session.lifetime=session
+----
+
+[[boot-features-spring-data-neo4j-application]]
+==== Application
+[source,java,indent=0]]
+----
+ @SpringBootApplication
+ @Import(Neo4jAutoConfiguration.class)
+ public class Application {
+
+ public static void main(String[] args) {
+ new SpringApplication(Application.class).run(args);
+ }
+
+ }
+----
+
+[[boot-features-neo4j-ogm-session]]
+==== Neo4jSession
+[source,java,indent=0]
+----
+ import org.springframework.beans.factory.annotation.Autowired;
+ import org.springframework.stereotype.Component;
+
+ import org.neo4j.ogm.session.Neo4jSession;
+
+ @Component
+ public class MyBean {
+
+ private final Session session;
+
+ @Autowired
+ public MyBean(Session session) {
+ this.session = session;
+ }
+
+ // ...
+ public void example() {
+ Iterable result = session.query("MATCH (c:Customer) RETURN count(*)",null);
+ // ...
+ }
+
+ }
+----
+
+[[boot-features-spring-data-neo4j-template]]
+==== Neo4jTemplate
+Spring Data Neo4j provides a
+{spring-data-neo4j-javadoc}/core/Neo4jTemplate.html[`Neo4jTemplate`] class that is very
+similar in its design to Spring's `JdbcTemplate`. As with `JdbcTemplate` Spring Boot
+auto-configures a bean for you to simply inject:
+
+[source,java,indent=0]
+----
+ import org.springframework.beans.factory.annotation.Autowired;
+ import org.springframework.stereotype.Component;
+
+ import org.springframework.data.neo4j.template.Neo4jTemplate;
+
+ @Component
+ public class MyBean {
+
+ private final Neo4jTemplate neo4jTemplate;
+
+ @Autowired
+ public MyBean(Neo4jTemplate neo4jTemplate) {
+ this.neo4jTemplate = neo4jTemplate;
+ }
+
+ // ...
+
+ }
+----
+
+See the `Neo4jOperations` Javadoc for complete details.
+
+[[boot-features-spring-data-neo4j-repositories]]
+==== Spring Data Neo4j repositories
+Spring Data includes repository support for Neo4j.
+
+In fact, both Spring Data JPA and Spring Data Neo4j share the same common
+infrastructure; so you could take the JPA example from earlier and, assuming that `City`
+is now a Neo4j OGM `@NodeEntity` rather than a JPA `@Entity`, it will work in the same way.
+
+To enable repository support (and optionally support for `@Transactional`), add the following two annotations to
+your Spring configuration:
+
+[source,java,indent=0]
+----
+ @EnableNeo4jRepositories(basePackages = "com.example.myapp.repository")
+ @EnableTransactionManagement
+----
+
+==== Repository example
+[source,java,indent=0]
+----
+ package com.example.myapp.domain;
+
+ import org.springframework.data.domain.*;
+ import org.springframework.data.repository.*;
+
+ public interface CityRepository extends GraphRepository {
+
+ Page findAll(Pageable pageable);
+
+ City findByNameAndCountry(String name, String country);
+
+ }
+----
+
+TIP: For complete details of Spring Data Neo4j, including its rich object mapping
+technologies, refer to their http://projects.spring.io/spring-data-neo4j/[reference
+documentation].
+
+
[[boot-features-gemfire]]
=== Gemfire
https://github.com/spring-projects/spring-data-gemfire[Spring Data Gemfire] provides
diff --git a/spring-boot-docs/src/main/asciidoc/using-spring-boot.adoc b/spring-boot-docs/src/main/asciidoc/using-spring-boot.adoc
index 01db16519e..d040454f67 100644
--- a/spring-boot-docs/src/main/asciidoc/using-spring-boot.adoc
+++ b/spring-boot-docs/src/main/asciidoc/using-spring-boot.adoc
@@ -420,6 +420,9 @@ and Hibernate.
|`spring-boot-starter-data-redis`
|Support for the REDIS key-value data store, including `spring-data-redis`.
+|`spring-boot-starter-data-neo4j`
+|Support for the Neo4j Graph Database, including `spring-data-neo4j`.
+
|`spring-boot-starter-data-rest`
|Support for exposing Spring Data repositories over REST via `spring-data-rest-webmvc`.
diff --git a/spring-boot-samples/spring-boot-sample-data-neo4j/pom.xml b/spring-boot-samples/spring-boot-sample-data-neo4j/pom.xml
new file mode 100644
index 0000000000..e87954e532
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-data-neo4j/pom.xml
@@ -0,0 +1,55 @@
+
+
+ 4.0.0
+
+
+ org.springframework.boot
+ spring-boot-samples
+ 1.4.0.BUILD-SNAPSHOT
+
+ spring-boot-sample-data-neo4j
+ Spring Boot Data Neo4j Sample
+ Spring Boot Data Neo4j Sample
+ http://projects.spring.io/spring-boot/
+
+ Pivotal Software, Inc.
+ http://www.spring.io
+
+
+ ${basedir}/../..
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-neo4j
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+ org.neo4j
+ neo4j-ogm-embedded-driver
+ 2.0.0-M04
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/spring-boot-samples/spring-boot-sample-data-neo4j/src/main/java/sample/data/neo4j/Customer.java b/spring-boot-samples/spring-boot-sample-data-neo4j/src/main/java/sample/data/neo4j/Customer.java
new file mode 100644
index 0000000000..4267e34b46
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-data-neo4j/src/main/java/sample/data/neo4j/Customer.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2012-2013 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package sample.data.neo4j;
+
+import org.neo4j.ogm.annotation.NodeEntity;
+import org.neo4j.ogm.annotation.GraphId;
+
+@NodeEntity
+public class Customer {
+
+ @GraphId
+ private Long id;
+
+ private String firstName;
+ private String lastName;
+
+ public Customer() {
+ }
+
+ public Customer(String firstName, String lastName) {
+ this.firstName = firstName;
+ this.lastName = lastName;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("Customer[id=%s, firstName='%s', lastName='%s']", id,
+ firstName, lastName);
+ }
+
+}
diff --git a/spring-boot-samples/spring-boot-sample-data-neo4j/src/main/java/sample/data/neo4j/CustomerRepository.java b/spring-boot-samples/spring-boot-sample-data-neo4j/src/main/java/sample/data/neo4j/CustomerRepository.java
new file mode 100644
index 0000000000..6c809b901f
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-data-neo4j/src/main/java/sample/data/neo4j/CustomerRepository.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2012-2013 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package sample.data.neo4j;
+
+import java.util.List;
+
+import org.springframework.data.neo4j.repository.GraphRepository;
+
+public interface CustomerRepository extends GraphRepository {
+
+ public Customer findByFirstName(String firstName);
+
+ public List findByLastName(String lastName);
+
+}
diff --git a/spring-boot-samples/spring-boot-sample-data-neo4j/src/main/java/sample/data/neo4j/SampleNeo4jApplication.java b/spring-boot-samples/spring-boot-sample-data-neo4j/src/main/java/sample/data/neo4j/SampleNeo4jApplication.java
new file mode 100644
index 0000000000..20b2c8ef46
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-data-neo4j/src/main/java/sample/data/neo4j/SampleNeo4jApplication.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2012-2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package sample.data.neo4j;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+import org.springframework.context.annotation.Import;
+
+@SpringBootApplication
+public class SampleNeo4jApplication implements CommandLineRunner {
+
+ @Autowired
+ private CustomerRepository repository;
+
+ @Override
+ public void run(String... args) throws Exception {
+ this.repository.deleteAll();
+
+ // save a couple of customers
+ this.repository.save(new Customer("Alice", "Smith"));
+ this.repository.save(new Customer("Bob", "Smith"));
+
+ // fetch all customers
+ System.out.println("Customers found with findAll():");
+ System.out.println("-------------------------------");
+ for (Customer customer : this.repository.findAll()) {
+ System.out.println(customer);
+ }
+ System.out.println();
+
+ // fetch an individual customer
+ System.out.println("Customer found with findByFirstName('Alice'):");
+ System.out.println("--------------------------------");
+ System.out.println(this.repository.findByFirstName("Alice"));
+
+ System.out.println("Customers found with findByLastName('Smith'):");
+ System.out.println("--------------------------------");
+ for (Customer customer : this.repository.findByLastName("Smith")) {
+ System.out.println(customer);
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ SpringApplication.run(SampleNeo4jApplication.class, args);
+ }
+
+}
diff --git a/spring-boot-samples/spring-boot-sample-data-neo4j/src/main/resources/application.properties b/spring-boot-samples/spring-boot-sample-data-neo4j/src/main/resources/application.properties
new file mode 100644
index 0000000000..b56c18a6b3
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-data-neo4j/src/main/resources/application.properties
@@ -0,0 +1,3 @@
+spring.data.neo4j.driver=org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver
+spring.data.neo4j.domain.packages=sample.data.neo4j
+spring.data.neo4j.session.lifetime=prototype
\ No newline at end of file
diff --git a/spring-boot-samples/spring-boot-sample-data-neo4j/src/test/java/sample/data/neo4j/SampleNeo4jApplicationTests.java b/spring-boot-samples/spring-boot-sample-data-neo4j/src/test/java/sample/data/neo4j/SampleNeo4jApplicationTests.java
new file mode 100644
index 0000000000..a7d445800c
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-data-neo4j/src/test/java/sample/data/neo4j/SampleNeo4jApplicationTests.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2012-2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package sample.data.neo4j;
+
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.IntegrationTest;
+import org.springframework.boot.test.OutputCapture;
+import org.springframework.boot.test.SpringApplicationConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests for {@link SampleNeo4jApplication}.
+ *
+ * @author Dave Syer
+ * @author Andy Wilkinson
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringApplicationConfiguration(SampleNeo4jApplication.class)
+@IntegrationTest
+public class SampleNeo4jApplicationTests {
+
+ @ClassRule
+ public static OutputCapture outputCapture = new OutputCapture();
+
+ @Test
+ public void testDefaultSettings() throws Exception {
+ String output = SampleNeo4jApplicationTests.outputCapture.toString();
+ assertTrue("Wrong output: " + output,
+ output.contains("firstName='Alice', lastName='Smith'"));
+ }
+
+}
diff --git a/spring-boot-starters/pom.xml b/spring-boot-starters/pom.xml
index e5667e3c3a..57c9258cdc 100644
--- a/spring-boot-starters/pom.xml
+++ b/spring-boot-starters/pom.xml
@@ -33,6 +33,7 @@
spring-boot-starter-data-gemfire
spring-boot-starter-data-jpa
spring-boot-starter-data-mongodb
+ spring-boot-starter-data-neo4j
spring-boot-starter-data-redis
spring-boot-starter-data-rest
spring-boot-starter-data-solr
@@ -69,6 +70,7 @@
spring-boot-starter-websocket
spring-boot-starter-ws
+
diff --git a/spring-boot-starters/spring-boot-starter-data-neo4j/pom.xml b/spring-boot-starters/spring-boot-starter-data-neo4j/pom.xml
new file mode 100644
index 0000000000..3a753b0c3e
--- /dev/null
+++ b/spring-boot-starters/spring-boot-starter-data-neo4j/pom.xml
@@ -0,0 +1,30 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starters
+ 1.4.0.BUILD-SNAPSHOT
+
+ spring-boot-starter-data-neo4j
+ Spring Boot Data Neo4j Starter
+ Spring Boot Data Neo4j Starter
+ http://projects.spring.io/spring-boot/
+
+ Pivotal Software, Inc.
+ http://www.spring.io
+
+
+ ${basedir}/../..
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.data
+ spring-data-neo4j
+
+
+
diff --git a/spring-boot-starters/spring-boot-starter-data-neo4j/src/main/resources/META-INF/spring.provides b/spring-boot-starters/spring-boot-starter-data-neo4j/src/main/resources/META-INF/spring.provides
new file mode 100644
index 0000000000..38cc6363c5
--- /dev/null
+++ b/spring-boot-starters/spring-boot-starter-data-neo4j/src/main/resources/META-INF/spring.provides
@@ -0,0 +1 @@
+provides: spring-data-neo4j
\ No newline at end of file