diff --git a/spring-data-neo4j-aspects/src/test/resources/org/springframework/data/neo4j/aspects/support/Neo4jGraphPersistenceTests-context.xml b/spring-data-neo4j-aspects/src/test/resources/org/springframework/data/neo4j/aspects/support/Neo4jGraphPersistenceTests-context.xml index df28c8ac4..b594b19ea 100644 --- a/spring-data-neo4j-aspects/src/test/resources/org/springframework/data/neo4j/aspects/support/Neo4jGraphPersistenceTests-context.xml +++ b/spring-data-neo4j-aspects/src/test/resources/org/springframework/data/neo4j/aspects/support/Neo4jGraphPersistenceTests-context.xml @@ -44,7 +44,7 @@ - + diff --git a/spring-data-neo4j-aspects/src/test/resources/org/springframework/data/neo4j/aspects/support/illegal-index1-tests-context.xml b/spring-data-neo4j-aspects/src/test/resources/org/springframework/data/neo4j/aspects/support/illegal-index1-tests-context.xml index 64b200683..1937d1997 100644 --- a/spring-data-neo4j-aspects/src/test/resources/org/springframework/data/neo4j/aspects/support/illegal-index1-tests-context.xml +++ b/spring-data-neo4j-aspects/src/test/resources/org/springframework/data/neo4j/aspects/support/illegal-index1-tests-context.xml @@ -11,7 +11,7 @@ - + @@ -67,4 +67,4 @@ - \ No newline at end of file + diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/config/DataGraphBeanDefinitionParser.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/config/DataGraphBeanDefinitionParser.java index 9103cd94f..1d6c4a44c 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/config/DataGraphBeanDefinitionParser.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/config/DataGraphBeanDefinitionParser.java @@ -33,6 +33,7 @@ public class DataGraphBeanDefinitionParser extends AbstractBeanDefinitionParser private static final String GRAPH_DATABASE_SERVICE = "graphDatabaseService"; private static final String BASE_PACKAGE = "base-package"; + private static final String CREATE_INDEX = "create-index"; public static final String ASPECTJ_CONFIG = "org.springframework.data.neo4j.aspects.config.Neo4jAspectConfiguration"; public static final String CROSS_STORE_CONFIG = "org.springframework.data.neo4j.cross_store.config.CrossStoreNeo4jConfiguration"; @@ -43,10 +44,17 @@ public class DataGraphBeanDefinitionParser extends AbstractBeanDefinitionParser setupGraphDatabase(element, context, configBuilder); setupEntityManagerFactory(element, configBuilder); setupBaseEntities(element, configBuilder); + setUpIndexCreation(element, configBuilder); setupConfigurationClassPostProcessor(context); return getSourcedBeanDefinition(configBuilder, element, context); } + private void setUpIndexCreation(Element element, BeanDefinitionBuilder configBuilder) { + String createIndexAttribute = element.getAttribute(CREATE_INDEX); + boolean createIndex = createIndexAttribute==null || !createIndexAttribute.equalsIgnoreCase("false"); + configBuilder.addPropertyValue("createIndex", createIndex); + } + private void setupBaseEntities(Element element, BeanDefinitionBuilder configBuilder) { Set initialEntityClasses = getInitialEntityClasses(element); if (initialEntityClasses!=null) { diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/config/Neo4jConfiguration.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/config/Neo4jConfiguration.java index a722cc0f0..039473784 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/config/Neo4jConfiguration.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/config/Neo4jConfiguration.java @@ -51,7 +51,6 @@ import org.springframework.data.neo4j.support.typerepresentation.TypeRepresentat import org.springframework.data.neo4j.support.typesafety.TypeSafetyPolicy; import org.springframework.data.support.IsNewStrategyFactory; import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.annotation.TransactionManagementConfigurer; import javax.validation.Validator; @@ -74,6 +73,7 @@ public abstract class Neo4jConfiguration { // implements TransactionManagementCo private ConversionService conversionService; private Set> initialEntitySet; + private boolean createIndex = true; @Autowired(required = false) private Validator validator; @@ -250,11 +250,12 @@ public abstract class Neo4jConfiguration { // implements TransactionManagementCo @Bean public EntityIndexCreator entityIndexCreator() throws Exception { - return new EntityIndexCreator( - indexProvider(), - schemaIndexProvider(), - nodeTypeRepresentationStrategy().isLabelBased() - ); + if (!createIndex) return new NoEntityIndexCreator(); + + return new DefaultEntityIndexCreator( + indexProvider(), + schemaIndexProvider(), + nodeTypeRepresentationStrategy().isLabelBased()); } @Bean @@ -299,6 +300,14 @@ public abstract class Neo4jConfiguration { // implements TransactionManagementCo this.initialEntitySet = initialEntitySet; } + public void setCreateIndex(boolean createIndex) { + this.createIndex = createIndex; + } + + public boolean isCreateIndex() { + return createIndex; + } + private String[] basePackage; diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/DefaultEntityIndexCreator.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/DefaultEntityIndexCreator.java new file mode 100644 index 000000000..195ff0483 --- /dev/null +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/DefaultEntityIndexCreator.java @@ -0,0 +1,67 @@ +/** + * Copyright 2011 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.data.neo4j.support.mapping; + +import org.springframework.data.mapping.PropertyHandler; +import org.springframework.data.neo4j.mapping.Neo4jPersistentEntity; +import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty; +import org.springframework.data.neo4j.support.index.IndexProvider; +import org.springframework.data.neo4j.support.index.IndexType; +import org.springframework.data.neo4j.support.schema.SchemaIndexProvider; + +/** + * @author mh + * @since 12.04.12 + */ +public class DefaultEntityIndexCreator implements EntityIndexCreator { + private IndexProvider indexProvider; + private SchemaIndexProvider schemaIndexProvider; + private boolean labelBased = true; + + public DefaultEntityIndexCreator(IndexProvider indexProvider, SchemaIndexProvider schemaIndexProvider) { + this(indexProvider, schemaIndexProvider,true); + } + public DefaultEntityIndexCreator(IndexProvider indexProvider, SchemaIndexProvider schemaIndexProvider, boolean labelBased) { + this.indexProvider = indexProvider; + this.schemaIndexProvider = schemaIndexProvider; + this.labelBased = labelBased; + } + + @Override + public void ensureEntityIndexes(Neo4jPersistentEntity entity) { + final Class entityType = entity.getType(); + + entity.doWithProperties(new PropertyHandler() { + @Override + public void doWithPersistentProperty(Neo4jPersistentProperty property) { + if (property.isIndexed() && property.getIndexInfo().isLabelBased()) { + schemaIndexProvider.createIndex(property); + } + } + }); + + // Pass 2 - do everything else + if (!labelBased) indexProvider.getIndex(entity, null, IndexType.SIMPLE); + entity.doWithProperties(new PropertyHandler() { + @Override + public void doWithPersistentProperty(Neo4jPersistentProperty property) { + if (property.isIndexed() && !property.getIndexInfo().isLabelBased()){ + indexProvider.getIndex(property, entityType); + } + } + }); + } +} diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/EntityIndexCreator.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/EntityIndexCreator.java index af8c6dcd5..4360b0569 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/EntityIndexCreator.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/EntityIndexCreator.java @@ -1,66 +1,11 @@ -/** - * Copyright 2011 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.data.neo4j.support.mapping; -import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.neo4j.mapping.Neo4jPersistentEntity; -import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty; -import org.springframework.data.neo4j.support.index.IndexProvider; -import org.springframework.data.neo4j.support.index.IndexType; -import org.springframework.data.neo4j.support.schema.SchemaIndexProvider; /** * @author mh - * @since 12.04.12 + * @since 19.10.14 */ -public class EntityIndexCreator { - private IndexProvider indexProvider; - private SchemaIndexProvider schemaIndexProvider; - private boolean labelBased = true; - - public EntityIndexCreator(IndexProvider indexProvider, SchemaIndexProvider schemaIndexProvider) { - this(indexProvider, schemaIndexProvider,true); - } - public EntityIndexCreator(IndexProvider indexProvider, SchemaIndexProvider schemaIndexProvider, boolean labelBased) { - this.indexProvider = indexProvider; - this.schemaIndexProvider = schemaIndexProvider; - this.labelBased = labelBased; - } - - public void ensureEntityIndexes(Neo4jPersistentEntity entity) { - final Class entityType = entity.getType(); - - entity.doWithProperties(new PropertyHandler() { - @Override - public void doWithPersistentProperty(Neo4jPersistentProperty property) { - if (property.isIndexed() && property.getIndexInfo().isLabelBased()) { - schemaIndexProvider.createIndex(property); - } - } - }); - - // Pass 2 - do everything else - if (!labelBased) indexProvider.getIndex(entity, null, IndexType.SIMPLE); - entity.doWithProperties(new PropertyHandler() { - @Override - public void doWithPersistentProperty(Neo4jPersistentProperty property) { - if (property.isIndexed() && !property.getIndexInfo().isLabelBased()){ - indexProvider.getIndex(property, entityType); - } - } - }); - } +public interface EntityIndexCreator { + void ensureEntityIndexes(Neo4jPersistentEntity entity); } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/Neo4jMappingContext.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/Neo4jMappingContext.java index 5fd0f88b1..98a6d4bce 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/Neo4jMappingContext.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/Neo4jMappingContext.java @@ -22,7 +22,6 @@ import org.neo4j.graphdb.Relationship; import org.neo4j.index.lucene.ValueContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.data.annotation.Reference; import org.springframework.data.mapping.context.AbstractMappingContext; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.model.MappingException; diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/NoEntityIndexCreator.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/NoEntityIndexCreator.java new file mode 100644 index 000000000..06bff4e38 --- /dev/null +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/NoEntityIndexCreator.java @@ -0,0 +1,13 @@ +package org.springframework.data.neo4j.support.mapping; + +import org.springframework.data.neo4j.mapping.Neo4jPersistentEntity; + +/** + * @author mh + * @since 19.10.14 + */ +public class NoEntityIndexCreator implements EntityIndexCreator { + @Override + public void ensureEntityIndexes(Neo4jPersistentEntity entity) { + } +} diff --git a/spring-data-neo4j/src/main/resources/META-INF/spring.schemas b/spring-data-neo4j/src/main/resources/META-INF/spring.schemas index cc2f5ca60..89d07abe1 100644 --- a/spring-data-neo4j/src/main/resources/META-INF/spring.schemas +++ b/spring-data-neo4j/src/main/resources/META-INF/spring.schemas @@ -1,4 +1,6 @@ http\://www.springframework.org/schema/data/neo4j/spring-neo4j-2.0.xsd=org/springframework/data/neo4j/config/spring-neo4j-2.0.xsd http\://www.springframework.org/schema/data/neo4j/spring-neo4j-2.1.xsd=org/springframework/data/neo4j/config/spring-neo4j-2.1.xsd http\://www.springframework.org/schema/data/neo4j/spring-neo4j-2.2.xsd=org/springframework/data/neo4j/config/spring-neo4j-2.2.xsd -http\://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd=org/springframework/data/neo4j/config/spring-neo4j-2.2.xsd \ No newline at end of file +http\://www.springframework.org/schema/data/neo4j/spring-neo4j-3.0.xsd=org/springframework/data/neo4j/config/spring-neo4j-3.0.xsd +http\://www.springframework.org/schema/data/neo4j/spring-neo4j-3.3.xsd=org/springframework/data/neo4j/config/spring-neo4j-3.3.xsd +http\://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd=org/springframework/data/neo4j/config/spring-neo4j-3.3.xsd diff --git a/spring-data-neo4j/src/main/resources/org/springframework/data/neo4j/config/spring-neo4j-3.3.xsd b/spring-data-neo4j/src/main/resources/org/springframework/data/neo4j/config/spring-neo4j-3.3.xsd new file mode 100644 index 000000000..a4e98f800 --- /dev/null +++ b/spring-data-neo4j/src/main/resources/org/springframework/data/neo4j/config/spring-neo4j-3.3.xsd @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + default store-directory of the Neo4j database + + + + + + + + + comma separated base package(s) for persistent entities. + + + + + + + entity manager factory bean reference for cross-store configuration + + + + + + + decides if schema and legacy indexes are created upfront for this application, defaults to true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/config/CreateIndexConfigTests.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/config/CreateIndexConfigTests.java new file mode 100644 index 000000000..d6864d9e9 --- /dev/null +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/config/CreateIndexConfigTests.java @@ -0,0 +1,80 @@ +package org.springframework.data.neo4j.config; + +import org.junit.After; +import org.junit.Test; +import org.neo4j.graphdb.GraphDatabaseService; +import org.neo4j.test.TestGraphDatabaseFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.context.support.FileSystemXmlApplicationContext; +import org.springframework.data.neo4j.support.mapping.DefaultEntityIndexCreator; +import org.springframework.data.neo4j.support.mapping.EntityIndexCreator; +import org.springframework.data.neo4j.support.mapping.NoEntityIndexCreator; + +import static org.junit.Assert.assertEquals; + +/** + * @author mh + * @since 19.10.14 + */ +public class CreateIndexConfigTests { + + private ApplicationContext ctx; + + static class DefaultTestConfiguration extends Neo4jConfiguration { + @Bean + public GraphDatabaseService graphDatabaseService() { + return new TestGraphDatabaseFactory().newImpermanentDatabase(); + } + } + + static class NoIndexTestConfiguration extends Neo4jConfiguration { + NoIndexTestConfiguration() { + setCreateIndex(false); + } + + @Bean + public GraphDatabaseService graphDatabaseService() { + return new TestGraphDatabaseFactory().newImpermanentDatabase(); + } + } + @Test + public void testEnableIndexWithNoConfig() throws Exception { + ctx = new AnnotationConfigApplicationContext(DefaultTestConfiguration.class); + EntityIndexCreator entityIndexCreator = ctx.getBean("entityIndexCreator", EntityIndexCreator.class); + assertEquals(DefaultEntityIndexCreator.class,entityIndexCreator.getClass()); + } + + @Test + public void testDisableIndexWithConstructorParam() throws Exception { + ctx = new AnnotationConfigApplicationContext(NoIndexTestConfiguration.class); + EntityIndexCreator entityIndexCreator = ctx.getBean("entityIndexCreator", EntityIndexCreator.class); + assertEquals(NoEntityIndexCreator.class,entityIndexCreator.getClass()); + } + @Test + public void testDisableIndexWithXmlConfig() throws Exception { + ctx = new ClassPathXmlApplicationContext("CreateIndexConfigTests-NoIndex-context.xml",getClass()); + EntityIndexCreator entityIndexCreator = ctx.getBean("entityIndexCreator", EntityIndexCreator.class); + assertEquals(NoEntityIndexCreator.class,entityIndexCreator.getClass()); + } + @Test + public void testEnableIndexWithDefaultXmlConfig() throws Exception { + ctx = new ClassPathXmlApplicationContext("CreateIndexConfigTests-DefaultIndex-context.xml",getClass()); + EntityIndexCreator entityIndexCreator = ctx.getBean("entityIndexCreator", EntityIndexCreator.class); + assertEquals(DefaultEntityIndexCreator.class,entityIndexCreator.getClass()); + } + @Test + public void testEnableIndexWithXmlConfig() throws Exception { + ctx = new ClassPathXmlApplicationContext("CreateIndexConfigTests-Index-context.xml",getClass()); + EntityIndexCreator entityIndexCreator = ctx.getBean("entityIndexCreator", EntityIndexCreator.class); + assertEquals(DefaultEntityIndexCreator.class,entityIndexCreator.getClass()); + } + + @After + public void tearDown() throws Exception { + if (ctx != null) ctx.close(); + + } +} diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/mapping/Neo4jPersistentTestBase.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/mapping/Neo4jPersistentTestBase.java index e7a64c8c6..ca8d41c27 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/mapping/Neo4jPersistentTestBase.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/mapping/Neo4jPersistentTestBase.java @@ -134,7 +134,7 @@ public class Neo4jPersistentTestBase { factoryBean.setNodeEntityStateFactory(nodeEntityStateFactory); factoryBean.setRelationshipEntityStateFactory(relationshipEntityStateFactory); - mappingContext.setEntityIndexCreator(new EntityIndexCreator(new IndexProviderImpl(graphDatabase), new SchemaIndexProvider(graphDatabase),true)); + mappingContext.setEntityIndexCreator(new DefaultEntityIndexCreator(new IndexProviderImpl(graphDatabase), new SchemaIndexProvider(graphDatabase),true)); mappingContext.setSimpleTypeHolder(null); setBasePackage(mappingContext); diff --git a/spring-data-neo4j/src/test/resources/org/springframework/data/neo4j/config/CreateIndexConfigTests-DefaultIndex-context.xml b/spring-data-neo4j/src/test/resources/org/springframework/data/neo4j/config/CreateIndexConfigTests-DefaultIndex-context.xml new file mode 100644 index 000000000..bf95b1ef4 --- /dev/null +++ b/spring-data-neo4j/src/test/resources/org/springframework/data/neo4j/config/CreateIndexConfigTests-DefaultIndex-context.xml @@ -0,0 +1,14 @@ + + + + + + + diff --git a/spring-data-neo4j/src/test/resources/org/springframework/data/neo4j/config/CreateIndexConfigTests-Index-context.xml b/spring-data-neo4j/src/test/resources/org/springframework/data/neo4j/config/CreateIndexConfigTests-Index-context.xml new file mode 100644 index 000000000..2dc95b44d --- /dev/null +++ b/spring-data-neo4j/src/test/resources/org/springframework/data/neo4j/config/CreateIndexConfigTests-Index-context.xml @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/spring-data-neo4j/src/test/resources/org/springframework/data/neo4j/config/CreateIndexConfigTests-NoIndex-context.xml b/spring-data-neo4j/src/test/resources/org/springframework/data/neo4j/config/CreateIndexConfigTests-NoIndex-context.xml new file mode 100644 index 000000000..2719d2e0f --- /dev/null +++ b/spring-data-neo4j/src/test/resources/org/springframework/data/neo4j/config/CreateIndexConfigTests-NoIndex-context.xml @@ -0,0 +1,14 @@ + + + + + + + diff --git a/src/main/asciidoc/reference/neo4j-server.adoc b/src/main/asciidoc/reference/neo4j-server.adoc index 1d1eefb4c..a0149d524 100644 --- a/src/main/asciidoc/reference/neo4j-server.adoc +++ b/src/main/asciidoc/reference/neo4j-server.adoc @@ -7,9 +7,9 @@ Neo4j is not only available in embedded mode. It can also be installed and run a When should you write a server extension? The default REST API is essentially a REST'ified representation of the Neo4j core API. It is nice for getting started, and for simpler scenarios. For more involved solutions that require high-volume access or more complex operations, writing a server extension that is able to process external parameters, do all the computations locally in the plugin, and then return just the relevant information to the calling client is preferable. -The Neo4j Server has two built-in extension mechanisms. It is possible to extend existing URI endpoints like the graph database, nodes, or relationships, adding new URIs or methods to those. This is achieved by writing a http://docs.neo4j.org/chunked/milestone/server-plugins.html[server plugin]. This plugin type has some restrictions however. +The Neo4j Server has two built-in extension mechanisms. It is possible to extend existing URI endpoints like the graph database, nodes, or relationships, adding new URIs or methods to those. This is achieved by writing a http://neo4j.com/docs/milestone/server-plugins.html[server plugin]. This plugin type has some restrictions however. -For complete freedom in the implementation, an http://docs.neo4j.org/chunked/milestone/server-unmanaged-extensions.html[unmanaged extension] can be used. Unmanaged extensions are essentially http://jersey.java.net/[Jersey] resource implementations. The resource constructors or methods can get the `GraphDatabaseService` injected to execute the necessary operations and return appropriate `Representations`. +For complete freedom in the implementation, an http://neo4j.com/docs/milestone/server-unmanaged-extensions.html[unmanaged extension] can be used. Unmanaged extensions are essentially http://jersey.java.net/[Jersey] resource implementations. The resource constructors or methods can get the `GraphDatabaseService` injected to execute the necessary operations and return appropriate `Representations`. Both kinds of extensions have to be packaged as JAR files and added to the Neo4j Server's plugin directory. Server Plugins are picked up by the server at startup if they provide the necessary `META-INF.services/org.neo4j.server.plugins.ServerPlugin` file for Java's ServiceLoader facility. Unmanaged extensions have to be registered with the Neo4j Server configuration. diff --git a/src/main/asciidoc/reference/neo4j.adoc b/src/main/asciidoc/reference/neo4j.adoc index 91c051176..ba90f1f45 100644 --- a/src/main/asciidoc/reference/neo4j.adoc +++ b/src/main/asciidoc/reference/neo4j.adoc @@ -13,7 +13,7 @@ http://neo4j.org/[Neo4j] is a NOSQL graph database. It is a fully transactional Neo4j has been in commercial development for 10 years and in production for over 7 years. Most importantly it has a helpful and contributing community surrounding it, but it also: -* has an intuitive, rich graph-oriented model for data representation. Instead of tables, rows, and columns, you work with a graph consisting of http://docs.neo4j.org/chunked/milestone/what-is-a-graphdb.html[nodes, relationships, and properties] +* has an intuitive, rich graph-oriented model for data representation. Instead of tables, rows, and columns, you work with a graph consisting of http://neo4j.com/docs/milestone/what-is-a-graphdb.html[nodes, relationships, and properties] * has a disk-based, native storage manager optimized for storing graph structures with maximum performance and scalability. * is scalable. Neo4j can handle graphs with many billions of nodes/relationships/properties on a single machine, but can also be scaled out across multiple machines for high availability. * has a powerful traversal framework and query languages for traversing the graph. @@ -101,7 +101,7 @@ try (Transaction tx = graphDb.beginTx()) { == Querying the Graph with Cypher -Neo4j provides a graph query language called http://docs.neo4j.org/chunked/milestone/cypher-query-lang.html["Cypher"] which draws from many sources. It resembles SQL but with an iconic representation of patterns in the graph (concepts drawn from SPARQL). The Cypher execution engine was written in Scala to leverage the high expressiveness for lazy sequence operations of the language and the parser combinator library. A screencast explaining the possibilities in detail can be found on the http://video.neo4j.org/ybMbf/screencast-introduction-to-cypher/[Neo4j video site]. +Neo4j provides a graph query language called http://neo4j.com/docs/milestone/cypher-query-lang.html["Cypher"] which draws from many sources. It resembles SQL but with an iconic representation of patterns in the graph (concepts drawn from SPARQL). The Cypher execution engine was written in Scala to leverage the high expressiveness for lazy sequence operations of the language and the parser combinator library. A screencast explaining the possibilities in detail can be found on the http://video.neo4j.org/ybMbf/screencast-introduction-to-cypher/[Neo4j video site]. As of Neo4 2.0, Cypher queries typically begin with a `match` clause, although the optional `start` clause (only really needed when using legacy indexes) is also still supported. The `match` clause can be used to provide a way to pattern match against a starting set of nodes, via their IDs or label based index lookup, with the legacy `start` clause providing similar functionality. These starting patterns or start nodes, are then related to other nodes via additional `match` clauses. Start and/or match clauses can introduce new identifiers for nodes and relationships. In the `where` clause additional filtering of the result set is applied by evaluating expressions. The `return` clause defines which part of the query result will be available. Aggregation also happens in the return clause by using aggregation functions on some of the values. Sorting can happen in the `order by` clause and the `skip` and `limit` parts restrict the result set to a certain window. diff --git a/src/main/asciidoc/reference/preface.adoc b/src/main/asciidoc/reference/preface.adoc index ac46d55d7..b9a74f373 100644 --- a/src/main/asciidoc/reference/preface.adoc +++ b/src/main/asciidoc/reference/preface.adoc @@ -9,7 +9,7 @@ The Spring Data Neo4j project, as part of the Spring Data initiative, aims to si Spring Data Neo4j allows, at any time, to drop down to the Neo4j-API level, see <> to execute functionality with the highest performance possible. -For integration of Neo4j and Grails/GORM please refer to the Neo4j http://www.grails.org/plugin/neo4j[grails plugin]. There are also http://docs.neo4j.org/chunked/milestone/python-embedded.html[Python bindings] as well as community-provided bindings to use Neo4j in http://docs.neo4j.org/chunked/milestone/languages.html[embedded] or http://docs.neo4j.org/chunked/milestone/tutorials-rest.html[REST mode]. +For integration of Neo4j and Grails/GORM please refer to the Neo4j http://www.grails.org/plugin/neo4j[grails plugin]. There are also http://neo4j.com/docs/milestone/python-embedded.html[Python bindings] as well as community-provided bindings to use Neo4j in http://neo4j.com/docs/milestone/languages.html[embedded] or http://neo4j.com/docs/milestone/tutorials-rest.html[REST mode]. == Reference Documentation Overview diff --git a/src/main/asciidoc/reference/programming-model/indexing.adoc b/src/main/asciidoc/reference/programming-model/indexing.adoc index 3357e575a..9173806cb 100644 --- a/src/main/asciidoc/reference/programming-model/indexing.adoc +++ b/src/main/asciidoc/reference/programming-model/indexing.adoc @@ -1,9 +1,9 @@ [[reference_programming-model_indexing]] = Indexing -Indexing is used in Neo4j to quickly find nodes and relationships to start graph operations from. Either for manually traversing the graph, using the traversal framework, cypher queries or for "global" graph operations. Indexes are also employed to ensure uniqueness of elements with certain properties. +Indexing is used in Neo4j to quickly find nodes and relationships to start graph operations from. Either for manually traversing the graph, using the traversal framework, cypher queries or for "global" graph operations. Indexes are also employed to ensure uniqueness of elements with certain labels and properties. -NOTE: Please note that the lucene based manual indexes are deprecated with Neo4j 2.0 and Spring Data Neo4j 3.0. The default index is now based on labels and schema indexes and the related APIs have been deprecated as well. The "legacy" index framework should only be used for fulltext and spatial indexes which are not currently supported via schema based indexes. +NOTE: Please note that the lucene based manual indexes are deprecated with Neo4j 2.0 and Spring Data Neo4j 3.0. The default index is now based on labels and schema indexes and the related old APIs have been deprecated as well. The "legacy" index framework should only be used for fulltext and spatial indexes which are not currently supported via schema based indexes. == Schema (Label based) indexes @@ -11,6 +11,12 @@ Since Neo4j version 2.0 indexes and unique constraints based on labels and prope Those indexes will be automatically used by cypher queries that are generated for the derived finders and are available for custom queries. +== Index Creation + +Indexes are created and updated upfront, when Spring Data Neo4j scans your entities and detects indexed fields. It will use an instance of `org.springframework.data.neo4j.support.mapping.EntityIndexCreator to create both schema based and legacy indexes. + +For certain setups, e.g. when your system is already set-up with all the indexes or when you run in an HA-cluster against a slave, you can disable this behavior by configuring `` or calling `Neo4jConfiguration.setCreateIndex(false)`. The default value is "true". + == Legacy indexes If you would like to force a property on an entity to rather use the legacy index (instead of the default schema based index), then you will need to explicitly specify the type as either `@Indexed(indexType = IndexType.SIMPLE)` or `@Indexed(indexType = IndexType.FULLTEXT)` @@ -96,8 +102,6 @@ Person mark = graphRepository.findAllByQuery("people-search", "name", "ma*"); ---- ==== -NOTE: Please note that the legacy indexes are currently created on demand, so whenever an index that doesn't exist is requested from a query or get operation it is created. This is subject to change but has currently the implication that those indexes won't be configured as fulltext which causes subsequent fulltext updates to those indexes to fail. - == Unique indexes Unique indexing can be applied either via the inbuilt schema (label based) unique constraint for nodes, or, via the legacy `index.putIfAbsent` and `UniqueFactory` code for both nodes and relationships. In Spring Data Neo4j this is done by setting the `unique=true` property on the `@Indexed` annotation. Methods for programmatically getting and/or creating unique entities is available on the `Neo4jTemplate` class, namely `getOrCreateNode` and `getOrCreateRelationship` for legacy indexes, and `merge` for schema based unique entities. @@ -209,7 +213,7 @@ For querying the index, the template offers query methods that take either the e == Neo4j Auto Indexes -Neo4j allows to configure http://docs.neo4j.org/chunked/milestone/auto-indexing.html[auto-indexing] for certain properties on nodes and relationships. This auto-indexing differs from the approach used in Spring Data Neo4j because it only updates the indexes when the transaction is committed. So the index modifications will only be available after the successful commit. It is possible to use the specific index names `node_auto_index` and `relationship_auto_index` when querying indexes in Spring Data Neo4j either with the query methods in template and repositories or via Cypher. +Neo4j allows to configure (legacy) http://neo4j.com/docs/milestone/auto-indexing.html[auto-indexing] for certain properties on nodes and relationships. This auto-indexing differs from the approach used in Spring Data Neo4j, because there is only one index across all nodes or relationships. It is possible to use the specific index names `node_auto_index` and `relationship_auto_index` when querying indexes in Spring Data Neo4j either with the query methods in template and repositories or via Cypher. == Spatial Indexes diff --git a/src/main/asciidoc/reference/programming-model/repositories.adoc b/src/main/asciidoc/reference/programming-model/repositories.adoc index bcd2dca94..eaabf9430 100644 --- a/src/main/asciidoc/reference/programming-model/repositories.adoc +++ b/src/main/asciidoc/reference/programming-model/repositories.adoc @@ -3,7 +3,7 @@ The repositories provided by Spring Data Neo4j build on the composable repository infrastructure in http://static.springsource.org/spring-data/data-commons/docs/current/reference/html/#repositories[Spring Data Commons]. They allow for interface based composition of repositories consisting of provided default implementations for certain interfaces and additional custom implementations for other methods. -Spring Data Neo4j repositories support annotated and named queries for the Neo4j http://docs.neo4j.org/chunked/milestone/query-lang.html[Cypher] query-language. +Spring Data Neo4j repositories support annotated and named queries for the Neo4j http://neo4j.com/docs/milestone/query-lang.html[Cypher] query-language. Spring Data Neo4j comes with typed repository implementations that provide methods for locating node and relationship entities. There are several types of basic repository interfaces and implementations. `CRUDRepository` provides basic operations, `IndexRepository` and `NamedIndexRepository` delegate to Neo4j's internal indexing subsystem for queries, and `TraversalRepository` handles Neo4j traversals. diff --git a/src/main/asciidoc/reference/setup.adoc b/src/main/asciidoc/reference/setup.adoc index 876ef3255..918b96b24 100644 --- a/src/main/asciidoc/reference/setup.adoc +++ b/src/main/asciidoc/reference/setup.adoc @@ -7,7 +7,7 @@ Spring Data Neo4j projects can be built using Maven. There are also means to bui == Dependencies for Spring Data Neo4j Simple Mapping -For the simple POJO mapping it is enough to add the `org.springframework.data:spring-data-neo4j:3.0.0.RELEASE` dependency to your project. +For the simple POJO mapping it is enough to add the `org.springframework.data:spring-data-neo4j:3.3.0.M1` dependency to your project. .Maven dependencies for Spring Data Neo4j ==== @@ -16,7 +16,7 @@ For the simple POJO mapping it is enough to add the `org.springframework.data:sp org.springframework.data spring-data-neo4j -3.0.0.RELEASE +3.3.0.M1 ---- ==== @@ -32,8 +32,8 @@ The necessary build plugin to build Spring Data Neo4j projects with Gradle is av sourceCompatibility = 1.6 targetCompatibility = 1.6 -springVersion = "3.2.8.RELEASE" -springDataNeo4jVersion = "3.0.0.RELEASE" +springVersion = "4.0.7.RELEASE" +springDataNeo4jVersion = "3.3.0.M1" aspectjVersion = "1.7.4" apply from:'https://github.com/SpringSource/spring-data-neo4j/raw/master/build/ @@ -110,13 +110,13 @@ The dependency on `spring-data-neo4j-aspects` will transitively pull in the nece org.springframework.data spring-data-neo4j-aspects - 3.0.0.RELEASE + 3.3.0.M1 org.aspectj aspectjrt - 1.7.4 + 1.8.2 ---- ==== @@ -134,16 +134,15 @@ Since the advanced mapping uses AspectJ for build-time aspect weaving of entitie aspectj-maven-plugin 1.4 - org.aspectj aspectjrt - 1.7.4 + 1.8.2 org.aspectj aspectjtools - 1.7.4 + 1.8.2 @@ -166,8 +165,8 @@ Since the advanced mapping uses AspectJ for build-time aspect weaving of entitie spring-data-neo4j-aspects - 1.6 - 1.6 + 1.7 + 1.7 ---- @@ -226,13 +225,27 @@ The XML namespace can be used to configure Spring Data Neo4j. The `config` eleme ---- ==== -.XML configuration with http://docs.neo4j.org/chunked/milestone/server-embedded.html[embedded Neo4j-Server] + +.XML configuration with disabled index creation (e.g. for HA-slave) +==== +[source,xml] +---- + + + +---- +==== + +.XML configuration with http://neo4j.com/docs/milestone/server-embedded.html[embedded Neo4j-Server] ==== [source,xml] ---- - @@ -286,7 +299,7 @@ As Spring Data Neo4j repositories build upon the infrastructure provided by http - + ---- ==== @@ -322,7 +335,7 @@ public class BasicJavaConfig extends Neo4jConfiguration { ---- ==== -.Java-based bean config initialiation via XML +.Java-based bean config initialization via XML ==== To register the default `@Configuration Neo4jConfiguration` class, as well as Spring's `ConfigurationClassPostProcessor` that transforms the `@Configuration` class to bean definitions via XML. @@ -338,9 +351,8 @@ To register the default `@Configuration Neo4jConfiguration` class, as well as Sp - - + ... diff --git a/src/main/asciidoc/tutorial/neo4j.adoc b/src/main/asciidoc/tutorial/neo4j.adoc index 88ee2cb35..c18742d0d 100644 --- a/src/main/asciidoc/tutorial/neo4j.adoc +++ b/src/main/asciidoc/tutorial/neo4j.adoc @@ -3,7 +3,7 @@ *_Graphs ahead_* -Now we needed to figure out how to store our chosen domain model in the chosen database. First we read up about graph databases, in particular our chosen one, http://neo4j.org[Neo4j]. The Neo4j data model consists of nodes and relationships, both of which can have key/value-style properties. What does that mean, exactly? Nodes are the graph database name for records, with property keys instead of column names. That's normal enough. Relationships are the special part. In Neo4j, relationships are first-class citizens, meaning they are more than a simple foreign-key reference to another record, relationships carry information. So we can link together nodes into semantically rich networks. This really appealed to us. Then we found that we were also able to http://docs.neo4j.org/chunked/milestone/indexing.html[index nodes and relationships] by {key, value} pairs. We also found that we could traverse relationships both imperatively using the core API, and declaratively using a query-like http://docs.neo4j.org/chunked/milestone/tutorials-java-embedded-traversal.html[Traversal Description]. Besides those programmatic traversals there was the powerful graph query language called http://docs.neo4j.org/chunked/milestone/cypher-query-lang.html[Cypher]. So lots of ways of working with the graph. +Now we needed to figure out how to store our chosen domain model in the chosen database. First we read up about graph databases, in particular our chosen one, http://neo4j.org[Neo4j]. The Neo4j data model consists of nodes and relationships, both of which can have key/value-style properties. What does that mean, exactly? Nodes are the graph database name for records, with property keys instead of column names. That's normal enough. Relationships are the special part. In Neo4j, relationships are first-class citizens, meaning they are more than a simple foreign-key reference to another record, relationships carry information. So we can link together nodes into semantically rich networks. This really appealed to us. Then we found that we were also able to http://neo4j.com/docs/milestone/indexing.html[index nodes and relationships] by {key, value} pairs. We also found that we could traverse relationships both imperatively using the core API, and declaratively using a query-like http://neo4j.com/docs/milestone/tutorials-java-embedded-traversal.html[Traversal Description]. Besides those programmatic traversals there was the powerful graph query language called http://neo4j.com/docs/milestone/cypher-query-lang.html[Cypher]. So lots of ways of working with the graph. We also learned that Neo4j is fully transactional and therefore upholds http://en.wikipedia.org/wiki/ACID[ACID] guarantees for our data. Durability is actually a good thing and we didn't have to scale to trillions of users and movies yet. This is unusual for NOSQL databases, but easier for us to get our head around than non-transactional eventual consistency. It also made us feel safe, though it also meant that we had to manage transactions. Something to keep in mind later.