Merge branch 'master' of github.com:SpringSource/spring-data-neo4j

This commit is contained in:
Michael Hunger
2012-04-17 09:36:26 +02:00
20 changed files with 214 additions and 39 deletions

View File

@@ -13,7 +13,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>3.0.7.RELEASE</spring.version>
<slf4j.version>1.6.1</slf4j.version>
<neo4j.version>1.6</neo4j.version>
<neo4j.version>1.7-SNAPSHOT</neo4j.version>
<spring-data-neo4j.version>${project.version}</spring-data-neo4j.version>
<aspectj.version>1.6.12</aspectj.version>
<org.slf4j-version>1.6.1</org.slf4j-version>

View File

@@ -13,7 +13,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>3.0.7.RELEASE</spring.version>
<slf4j.version>1.6.1</slf4j.version>
<neo4j.version>1.6</neo4j.version>
<neo4j.version>1.7-SNAPSHOT</neo4j.version>
<spring-data-neo4j.version>${project.version}</spring-data-neo4j.version>
<aspectj.version>1.6.12</aspectj.version>
<org.slf4j-version>1.6.1</org.slf4j-version>
@@ -340,10 +340,10 @@
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.fileinstall</artifactId>
</exclusion>
<exclusion>
<!--exclusion>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-shell</artifactId>
</exclusion>
</exclusion-->
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>

View File

@@ -17,7 +17,7 @@
<!--<bean id="graphDatabaseService" class="org.neo4j.test.ImpermanentGraphDatabase"/>-->
<bean id="graphDatabaseService" class="org.springframework.data.neo4j.rest.SpringRestGraphDatabase" scope="singleton">
<constructor-arg index="0" value="http://localhost:7473/db/data" />
<constructor-arg index="0" value="http://localhost:7470/db/data" />
</bean>
<bean class="org.neo4j.cineasts.movieimport.MovieDbApiClient">
<constructor-arg value="926d2a79e82920b62f03b1cb57e532e6"/>

View File

@@ -16,7 +16,7 @@
<spring-data-neo4j.version>${project.version}</spring-data-neo4j.version>
<org.slf4j-version>1.6.1</org.slf4j-version>
<aspectj.version>1.6.12</aspectj.version>
<neo4j.version>1.6</neo4j.version>
<neo4j.version>1.7-SNAPSHOT</neo4j.version>
</properties>
<repositories>

View File

@@ -11,7 +11,7 @@
<spring-data-neo4j.version>${project.version}</spring-data-neo4j.version>
<aspectj.version>1.6.12</aspectj.version>
<slf4j.version>1.6.1</slf4j.version>
<neo4j.version>1.6</neo4j.version>
<neo4j.version>1.7-SNAPSHOT</neo4j.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-security.version>3.0.7.RELEASE</spring-security.version>
</properties>

View File

@@ -11,7 +11,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<neo4j.version>1.6</neo4j.version>
<neo4j.version>1.7-SNAPSHOT</neo4j.version>
<spring.version>3.0.7.RELEASE</spring.version>
<spring-data-neo4j.version>${project.version}</spring-data-neo4j.version>
<aspectj.version>1.6.12</aspectj.version>
@@ -193,7 +193,6 @@
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
<classifier />
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
@@ -205,7 +204,6 @@
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
<classifier />
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>

View File

@@ -126,7 +126,7 @@
<org.springframework.version.30>3.0.7.RELEASE</org.springframework.version.30>
<org.springframework.version.40>4.0.0.RELEASE</org.springframework.version.40>
<org.springframework.version>[${org.springframework.version.30}, ${org.springframework.version.40})</org.springframework.version>
<data.commons.version>1.2.1.RELEASE</data.commons.version>
<data.commons.version>1.3.0.RC1</data.commons.version>
<neo4j.version>1.7-SNAPSHOT</neo4j.version>
<neo4j.spatial.version>0.8-SNAPSHOT</neo4j.spatial.version>
<aspectj.version>1.6.12</aspectj.version>
@@ -345,7 +345,7 @@
<groupId>com.tinkerpop.gremlin</groupId>
<artifactId>gremlin-groovy</artifactId>
<version>${gremlin.version}</version>
<type>jar</type>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>org.neo4j</groupId>
@@ -404,13 +404,6 @@
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.tinkerpop.gremlin</groupId>
<artifactId>gremlin-groovy</artifactId>
<version>${gremlin.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
@@ -467,7 +460,7 @@
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-cypher-dsl</artifactId>
<version>1.6.M02</version>
<version>${neo4j.version}</version>
<!--optional>true</optional-->
</dependency>
<dependency>
@@ -771,14 +764,23 @@
<repository>
<id>tinkerpop-repository</id>
<url>http://tinkerpop.com/maven2</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>jboss-repository</id>
<url>http://repository.jboss.org/nexus/content/groups/public-jboss</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>neo4j-public-release-repository</id>
<url>http://m2.neo4j.org/releases</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>neo4j-public-snapshot-repository</id>

View File

@@ -33,7 +33,7 @@ public class RestTestBase {
protected SpringRestGraphDatabase restGraphDatabase;
private static final String HOSTNAME = "127.0.0.1";
public static final int PORT = 7473;
public static final int PORT = 7470;
protected static LocalTestServer neoServer = new LocalTestServer(HOSTNAME,PORT).withPropertiesFile("test-db.properties");
public static final String SERVER_ROOT_URI = "http://" + HOSTNAME + ":" + PORT + "/db/data/";

View File

@@ -28,7 +28,7 @@ public class RestTestHelper
protected SpringRestGraphDatabase graphDb;
private static final String HOSTNAME = "localhost";
private static final int PORT = 7473;
private static final int PORT = 7470;
private static LocalTestServer neoServer;
private static final String SERVER_ROOT_URI = "http://" + HOSTNAME + ":" + PORT + "/db/data/";

View File

@@ -42,7 +42,7 @@ public class SpringPluginInitializerTest extends SpringPluginInitializer impleme
private static int touched = 0;
private static final String HOSTNAME = "localhost";
private static final int PORT = 7473;
private static final int PORT = 7470;
@Path( "/testInterface" )
@POST
@@ -87,7 +87,7 @@ public class SpringPluginInitializerTest extends SpringPluginInitializer impleme
private RequestResult sendRequest( String method ) {
return RequestResult.extractFrom(Client.create().
resource( "http://localhost:7473/test/" + method ).
resource( "http://"+HOSTNAME+":"+PORT+"/test/" + method ).
type( MediaType.APPLICATION_JSON ).
accept( MediaType.APPLICATION_JSON ).post( ClientResponse.class ));
}

View File

@@ -15,6 +15,6 @@
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="graphDatabaseService" class="org.springframework.data.neo4j.rest.SpringRestGraphDatabase" scope="singleton">
<constructor-arg index="0" value="http://localhost:7473/db/data" />
<constructor-arg index="0" value="http://localhost:7470/db/data" />
</bean>
</beans>

View File

@@ -128,7 +128,6 @@
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-cypher-dsl</artifactId>
<!--optional>true</optional-->
</dependency>
<dependency>
<groupId>org.neo4j</groupId>

View File

@@ -46,6 +46,7 @@ import org.springframework.data.neo4j.support.index.IndexProviderImpl;
import org.springframework.data.neo4j.support.mapping.ClassNameAlias;
import org.springframework.data.neo4j.support.mapping.EntityAlias;
import org.springframework.data.neo4j.support.mapping.EntityStateHandler;
import org.springframework.data.neo4j.support.mapping.IndexCreationMappingEventListener;
import org.springframework.data.neo4j.support.mapping.Neo4jEntityFetchHandler;
import org.springframework.data.neo4j.support.mapping.Neo4jMappingContext;
import org.springframework.data.neo4j.support.mapping.SourceStateTransmitter;
@@ -241,6 +242,11 @@ public abstract class Neo4jConfiguration {
return createJtaTransactionManager();
}
@Bean
public IndexCreationMappingEventListener indexCreationMappingEventListener() throws Exception {
return new IndexCreationMappingEventListener(neo4jTemplate());
}
protected JtaTransactionManager createJtaTransactionManager() {
JtaTransactionManager jtaTm = new JtaTransactionManager();
final GraphDatabaseService gds = getGraphDatabaseService();

View File

@@ -104,17 +104,17 @@ public abstract class AbstractGraphRepository<S extends PropertyContainer, T> im
}
@Override
public T save(T entity) {
return (T) template.save(entity);
public <U extends T> U save(U entity) {
return template.save(entity);
}
@SuppressWarnings("unchecked")
@Override
public Iterable<T> save(Iterable<? extends T> entities) {
for (T entity : entities) {
public <U extends T> Iterable<U> save(Iterable<U> entities) {
for (U entity : entities) {
save(entity);
}
return (Iterable<T>) entities;
return (Iterable<U>) entities;
}
/**
@@ -358,6 +358,33 @@ public abstract class AbstractGraphRepository<S extends PropertyContainer, T> im
return page;
}
@Override
public Iterable<T> findAll(final Iterable<Long> ids) {
return new Iterable<T>() {
@Override
public Iterator<T> iterator() {
final Iterator<Long> idIterator = ids.iterator();
return new Iterator<T>() {
@Override
public boolean hasNext() {
return idIterator.hasNext();
}
@Override
public T next() {
return template.findOne(idIterator.next(), clazz);
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}
private PageImpl<T> extractPage(Pageable pageable, int count, int offset, Iterator<T> iterator) {
final List<T> result = new ArrayList<T>(count);
int total=subList(offset, count, iterator, result);

View File

@@ -38,7 +38,7 @@ public interface CRUDRepository<T> extends PagingAndSortingRepository<T, Long> {
* @return the saved entity (being the same reference as the parameter)
*/
@Transactional
T save(T entity);
<U extends T> U save(U entity);
/**
@@ -47,7 +47,7 @@ public interface CRUDRepository<T> extends PagingAndSortingRepository<T, Long> {
* @return the input iterable
*/
@Transactional
Iterable<T> save(Iterable<? extends T> entities);
<U extends T> Iterable<U> save(Iterable<U> entities);
/**

View File

@@ -0,0 +1,53 @@
/**
* 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.context.ApplicationListener;
import org.springframework.data.mapping.PropertyHandler;
import org.springframework.data.mapping.event.MappingContextEvent;
import org.springframework.data.neo4j.mapping.Neo4jPersistentEntity;
import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.data.neo4j.support.index.IndexType;
/**
* @author mh
* @since 12.04.12
*/
public class IndexCreationMappingEventListener implements ApplicationListener<MappingContextEvent<Neo4jPersistentEntity<?>, Neo4jPersistentProperty>> {
private Neo4jTemplate template;
public IndexCreationMappingEventListener(Neo4jTemplate template) {
this.template = template;
}
@Override
public void onApplicationEvent(MappingContextEvent<Neo4jPersistentEntity<?>, Neo4jPersistentProperty> event) {
if (!(event.getSource() instanceof Neo4jPersistentEntity)) return;
final Neo4jPersistentEntity entity = event.getPersistentEntity();
final Class entityType = entity.getType();
template.getIndex(entityType, null, IndexType.SIMPLE);
entity.doWithProperties(new PropertyHandler<Neo4jPersistentProperty>() {
@Override
public void doWithPersistentProperty(Neo4jPersistentProperty property) {
if (property.isIndexed()) {
template.getIndex(property, entityType);
}
}
});
}
}

View File

@@ -18,14 +18,43 @@ package org.springframework.data.neo4j.support.node;
import org.neo4j.graphdb.*;
import org.neo4j.graphdb.index.IndexManager;
import org.neo4j.tooling.GlobalGraphOperations;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import java.util.HashMap;
import java.util.Map;
public abstract class Neo4jHelper {
public static void cleanDb(Neo4jTemplate template) {
cleanDb(template.getGraphDatabaseService());
}
public static void dumpDb(GraphDatabaseService gds) {
final GlobalGraphOperations globalGraphOperations = GlobalGraphOperations.at(gds);
for (Node node : globalGraphOperations.getAllNodes()) {
System.out.println(dump(node));
}
for (Node node : globalGraphOperations.getAllNodes()) {
for (Relationship rel : node.getRelationships(Direction.OUTGOING)) {
System.out.println(node +"-[:"+rel.getType().name() +" "+dump(rel)+"]->"+rel.getEndNode());
}
}
}
private static String dump(PropertyContainer pc) {
final long id = pc instanceof Node ? ((Node) pc).getId() : ((Relationship) pc).getId();
try {
Map<String, Object> props = new HashMap<String, Object>();
for (String prop : pc.getPropertyKeys()) {
props.put(prop, pc.getProperty(prop));
}
return String.format("(%d) %s ", id, props);
} catch (Exception e) {
return "(" + id + ") " + e.getMessage();
}
}
public static void cleanDb(GraphDatabaseService graphDatabaseService) {
Transaction tx = graphDatabaseService.beginTx();
@@ -39,13 +68,14 @@ public abstract class Neo4jHelper {
}
private static void removeNodes(GraphDatabaseService graphDatabaseService) {
final GlobalGraphOperations globalGraphOperations = GlobalGraphOperations.at(graphDatabaseService);
Node refNode = graphDatabaseService.getReferenceNode();
for (Node node : graphDatabaseService.getAllNodes()) {
for (Node node : globalGraphOperations.getAllNodes()) {
for (Relationship rel : node.getRelationships(Direction.OUTGOING)) {
rel.delete();
}
}
for (Node node : graphDatabaseService.getAllNodes()) {
for (Node node : globalGraphOperations.getAllNodes()) {
if (!refNode.equals(node)) {
node.delete();
}

View File

@@ -0,0 +1,58 @@
/**
* 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.repository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.neo4j.helpers.collection.IteratorUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.neo4j.model.Person;
import org.springframework.test.context.CleanContextCacheTestExecutionListener;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
import org.springframework.transaction.annotation.Transactional;
import static org.junit.Assert.assertEquals;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:org/springframework/data/neo4j/repository/GraphRepositoryTest-context.xml")
@TestExecutionListeners({CleanContextCacheTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, TransactionalTestExecutionListener.class})
public class NoIndexDerivedFinderTest {
protected final Logger log = LoggerFactory.getLogger(getClass());
@Autowired
private PersonRepository personRepository;
@Test @Transactional
public void findByAge() {
Iterable<Person> result = personRepository.findByAge(0);
assertEquals(0,IteratorUtil.count(result));
}
@Test @Transactional
public void findByName() {
Iterable<Person> result = personRepository.findByName("");
assertEquals(0,IteratorUtil.count(result));
}
}

View File

@@ -77,5 +77,7 @@ public interface PersonRepository extends GraphRepository<Person>, NamedIndexRep
Iterable<Person> findByName(String name);
Iterable<Person> findByPersonality(String personality);
Iterable<Person> findByAge(int age);
}

View File

@@ -74,9 +74,9 @@ public class FullNeo4jTemplateTest {
@Before
public void setUp() throws Exception {
Neo4jHelper.cleanDb(neo4jTemplate);
// graphDatabase = neo4jTemplate.getGraphDatabase();
referenceNode = graphDatabase.getReferenceNode();
createData();
Neo4jHelper.dumpDb(neo4jTemplate.getGraphDatabaseService());
}
private void createData() {
@@ -285,17 +285,17 @@ public class FullNeo4jTemplateTest {
@Test
public void shouldFindNextNodeViaCypher() throws Exception {
assertSingleResult(node1, neo4jTemplate.query("start n=node(0) match n-->m return m", null).to(Node.class));
assertSingleResult(node1, neo4jTemplate.query("start n=node(0) match n-[:knows]->m return m", null).to(Node.class));
}
@Test
public void shouldFindNextNodeViaGremlin() throws Exception {
assertSingleResult(node1, neo4jTemplate.execute("g.v(0).out", null).to(Node.class));
assertSingleResult(node1, neo4jTemplate.execute("g.v(0).outE.filter{it.label=='knows'}.inV", null).to(Node.class));
}
@Test
public void shouldGetDirectRelationship() throws Exception {
assertSingleResult("rel1", neo4jTemplate.convert(referenceNode.getRelationships()).to(String.class, new RelationshipNameConverter()));
assertSingleResult("rel1", neo4jTemplate.convert(referenceNode.getRelationships(DynamicRelationshipType.withName("knows"))).to(String.class, new RelationshipNameConverter()));
}
@Test