Commit 0658cc8a authored by Michael Hunger's avatar Michael Hunger Committed by Stephane Nicoll

Add Neo4j support

See gh-5458
parent a413acee
......@@ -166,6 +166,11 @@
<artifactId>spring-data-mongodb</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
......
......@@ -379,6 +379,17 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<artifactId>jcl-over-slf4j</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
......@@ -635,5 +646,6 @@
<artifactId>tomcat-embed-jasper</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
......@@ -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)
......
/*
* 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.
* <p>
* 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();
}
}
/*
* 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;
}
}
/*
* 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.
* <p>
* 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}.
* <p>
* 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 {
}
/*
* 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 {
}
}
/*
* 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;
......@@ -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",
......
......@@ -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,\
......
/*
* 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<City> {
}
/*
* 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<String> names = new ArrayList<String>();
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()]);
}
}
}
/*
* 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 {
}
}
/*
* 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();
}
}
/*
* 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<City> {
Page<City> findAll(Pageable pageable);
// TODO: cannot resolve queries like this at the moment.
//
// Page<City> findByNameLikeAndCountryLikeAllIgnoringCase(String name, String country,
// Pageable pageable);
//
// City findByNameAndCountry(String name, String country);
}
/*
* 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();
}
}
/*
* 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<Country> {
}
/*
* 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);
}
}
/*
* 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();
}
}
}
/*
* 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 {
}
}
......@@ -55,9 +55,11 @@
<cassandra-driver.version>2.1.9</cassandra-driver.version>
<commons-beanutils.version>1.9.2</commons-beanutils.version>
<commons-collections.version>3.2.2</commons-collections.version>
<commons-codec.version>1.10</commons-codec.version>
<commons-dbcp.version>1.4</commons-dbcp.version>
<commons-dbcp2.version>2.1.1</commons-dbcp2.version>
<commons-digester.version>2.1</commons-digester.version>
<commons-lang3.version>3.4</commons-lang3.version>
<commons-pool.version>1.6</commons-pool.version>
<commons-pool2.version>2.4.2</commons-pool2.version>
<couchbase-client.version>2.2.3</couchbase-client.version>
......@@ -325,6 +327,11 @@
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>1.4.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
<version>1.4.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
......@@ -768,11 +775,17 @@
<artifactId>commons-collections</artifactId>
<version>${commons-collections.version}</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>${commons-codec.version}</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>${commons-dbcp.version}</version>
</dependency>
<dependency>
<groupId>commons-digester</groupId>
<artifactId>commons-digester</artifactId>
......@@ -2149,6 +2162,7 @@
<artifactId>wsdl4j</artifactId>
<version>${wsdl4j.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
......
......@@ -488,6 +488,11 @@
<artifactId>spring-data-mongodb</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
......
......@@ -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<City> {
Page<City> 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
......
......@@ -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`.
......
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<!-- Your own application should inherit from spring-boot-starter-parent -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-samples</artifactId>
<version>1.4.0.BUILD-SNAPSHOT</version>
</parent>
<artifactId>spring-boot-sample-data-neo4j</artifactId>
<name>Spring Boot Data Neo4j Sample</name>
<description>Spring Boot Data Neo4j Sample</description>
<url>http://projects.spring.io/spring-boot/</url>
<organization>
<name>Pivotal Software, Inc.</name>
<url>http://www.spring.io</url>
</organization>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-embedded-driver</artifactId>
<version>2.0.0-M04</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
/*
* 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);
}
}
/*
* 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<Customer> {
public Customer findByFirstName(String firstName);
public List<Customer> findByLastName(String lastName);
}
/*
* 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);
}
}
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
/*
* 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'"));
}
}
......@@ -33,6 +33,7 @@
<module>spring-boot-starter-data-gemfire</module>
<module>spring-boot-starter-data-jpa</module>
<module>spring-boot-starter-data-mongodb</module>
<module>spring-boot-starter-data-neo4j</module>
<module>spring-boot-starter-data-redis</module>
<module>spring-boot-starter-data-rest</module>
<module>spring-boot-starter-data-solr</module>
......@@ -69,6 +70,7 @@
<module>spring-boot-starter-websocket</module>
<module>spring-boot-starter-ws</module>
</modules>
<build>
<plugins>
<plugin>
......
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starters</artifactId>
<version>1.4.0.BUILD-SNAPSHOT</version>
</parent>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
<name>Spring Boot Data Neo4j Starter</name>
<description>Spring Boot Data Neo4j Starter</description>
<url>http://projects.spring.io/spring-boot/</url>
<organization>
<name>Pivotal Software, Inc.</name>
<url>http://www.spring.io</url>
</organization>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
</dependency>
</dependencies>
</project>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment