DATAGRAPH-423 Upgrade to Neo4j 2.0 GA release
* read transaction * removal of reference node * fixing tests * updating dependencies
This commit is contained in:
@@ -56,14 +56,11 @@ for (Node actor : actors.traverse(movie))
|
||||
|
||||
<h4>Transactional: TX needed for write operations</h4>
|
||||
<pre>
|
||||
Transaction tx=graphDatabaseService.beginTx();
|
||||
try {
|
||||
try (Transaction tx=graphDatabaseService.beginTx()) {
|
||||
... graph operations ...
|
||||
tx.success();
|
||||
} catch(Exception e) {
|
||||
tx.failure();
|
||||
} finally {
|
||||
tx.finish();
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
22
pom.xml
22
pom.xml
@@ -38,11 +38,11 @@
|
||||
<source.level>1.7</source.level>
|
||||
<target.level>1.7</target.level>
|
||||
|
||||
<neo4j.version>2.0.0-M06</neo4j.version>
|
||||
<neo4j.version>2.0.0</neo4j.version>
|
||||
|
||||
<neo4j.spatial.version>0.12-neo4j-2.0.0-M06</neo4j.spatial.version>
|
||||
<neo4j.graph-collections.version>0.7.1-neo4j-2.0.0-M06</neo4j.graph-collections.version>
|
||||
<neo4j-cypher-dsl.version>2.0.0-M06</neo4j-cypher-dsl.version>
|
||||
<neo4j.spatial.version>0.12-neo4j-2.0.0</neo4j.spatial.version>
|
||||
<neo4j.graph-collections.version>0.7.1-neo4j-2.0.0</neo4j.graph-collections.version>
|
||||
<neo4j-cypher-dsl.version>2.0.0</neo4j-cypher-dsl.version>
|
||||
</properties>
|
||||
|
||||
|
||||
@@ -182,13 +182,13 @@
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>tinkerpop-repository</id>
|
||||
<url>http://tinkerpop.com/maven2</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>neo4j-contrib-releases</id>
|
||||
<url>https://raw.github.com/neo4j-contrib/m2/master/releases</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
|
||||
@@ -23,7 +23,6 @@ import org.neo4j.graphdb.Relationship;
|
||||
import org.neo4j.graphdb.traversal.Evaluators;
|
||||
import org.neo4j.graphdb.traversal.TraversalDescription;
|
||||
import org.neo4j.kernel.Traversal;
|
||||
import org.neo4j.kernel.impl.traversal.TraversalDescriptionImpl;
|
||||
import org.springframework.data.neo4j.annotation.*;
|
||||
import org.springframework.data.neo4j.core.FieldTraversalDescriptionBuilder;
|
||||
import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty;
|
||||
@@ -183,7 +182,7 @@ public class Group {
|
||||
private static class PeopleTraversalBuilder implements FieldTraversalDescriptionBuilder {
|
||||
@Override
|
||||
public TraversalDescription build(Object start, Neo4jPersistentProperty property, String...params) {
|
||||
return new TraversalDescriptionImpl()
|
||||
return Traversal.description()
|
||||
.relationships(DynamicRelationshipType.withName(params[0]))
|
||||
.evaluator(Evaluators.excludeStartPosition());
|
||||
|
||||
|
||||
@@ -88,13 +88,10 @@ public class EntityTestBase {
|
||||
}
|
||||
|
||||
protected void manualCleanDb() {
|
||||
Transaction tx = graphDatabaseService.beginTx();
|
||||
try {
|
||||
cleanDb();
|
||||
tx.success();
|
||||
} finally {
|
||||
tx.finish();
|
||||
}
|
||||
try (Transaction tx = graphDatabaseService.beginTx()) {
|
||||
cleanDb();
|
||||
tx.success();
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeTransaction
|
||||
|
||||
@@ -93,14 +93,11 @@ public class IndexTests extends EntityTestBase {
|
||||
//@Transactional
|
||||
//@Ignore("remove property from index not workin")
|
||||
public void testRemovePropertyFromIndex() {
|
||||
Transaction tx = neo4jTemplate.getGraphDatabase().beginTx();
|
||||
try {
|
||||
try (Transaction tx = neo4jTemplate.getGraphDatabase().beginTx()) {
|
||||
Group group = persist(new Group());
|
||||
group.setName(NAME_VALUE);
|
||||
getGroupIndex().remove(getNodeState(group), NAME);
|
||||
tx.success();
|
||||
} finally {
|
||||
tx.finish();
|
||||
}
|
||||
final Group found = this.groupRepository.findByPropertyValue(NAME, NAME_VALUE);
|
||||
assertNull("Group.name removed from index", found);
|
||||
@@ -272,7 +269,7 @@ public class IndexTests extends EntityTestBase {
|
||||
group2.setName(NAME_VALUE);
|
||||
final Iterable<Group> found = this.groupRepository.findAllByPropertyValue(NAME, NAME_VALUE);
|
||||
final Collection<Group> result = IteratorUtil.addToCollection(found.iterator(), new HashSet<Group>());
|
||||
assertEquals(new HashSet<Group>(Arrays.asList(group, group2)), result);
|
||||
assertEquals(new HashSet<>(Arrays.asList(group, group2)), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -298,7 +295,7 @@ public class IndexTests extends EntityTestBase {
|
||||
group.setFullTextName("queryableName");
|
||||
final Iterable<Group> found = groupRepository.findAllByQuery(Group.SEARCH_GROUPS_INDEX, "fullTextName", "queryable*");
|
||||
final Collection<Group> result = IteratorUtil.addToCollection(found.iterator(), new HashSet<Group>());
|
||||
assertEquals(new HashSet<Group>(Arrays.asList(group)), result);
|
||||
assertEquals(new HashSet<>(Arrays.asList(group)), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -371,7 +368,7 @@ public class IndexTests extends EntityTestBase {
|
||||
p = persistedPerson(NAME_VALUE2, 30);
|
||||
tx.success();
|
||||
} finally {
|
||||
if (tx != null) tx.finish();
|
||||
if (tx != null) tx.close();
|
||||
}
|
||||
Assert.assertEquals(p, personRepository.findByPropertyValue(NAME_INDEX, "name", NAME_VALUE2));
|
||||
try {
|
||||
@@ -379,7 +376,7 @@ public class IndexTests extends EntityTestBase {
|
||||
p.setName(NAME_VALUE);
|
||||
tx.success();
|
||||
} finally {
|
||||
tx.finish();
|
||||
tx.close();
|
||||
}
|
||||
Assert.assertEquals(p, personRepository.findByPropertyValue(NAME_INDEX, "name", NAME_VALUE));
|
||||
try {
|
||||
@@ -387,7 +384,7 @@ public class IndexTests extends EntityTestBase {
|
||||
p.setName(NAME_VALUE2);
|
||||
tx.success();
|
||||
} finally {
|
||||
tx.finish();
|
||||
tx.close();
|
||||
}
|
||||
Assert.assertEquals(p, personRepository.findByPropertyValue(NAME_INDEX, "name", NAME_VALUE2));
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.neo4j.graphdb.traversal.Evaluators;
|
||||
import org.neo4j.graphdb.traversal.TraversalDescription;
|
||||
import org.neo4j.helpers.collection.IteratorUtil;
|
||||
import org.neo4j.kernel.Traversal;
|
||||
import org.neo4j.kernel.impl.traversal.TraversalDescriptionImpl;
|
||||
import org.springframework.data.neo4j.aspects.Group;
|
||||
import org.springframework.data.neo4j.aspects.Person;
|
||||
import org.springframework.data.neo4j.core.EntityPath;
|
||||
@@ -112,7 +111,7 @@ public class TraversalTests extends EntityTestBase {
|
||||
Group group = persist(new Group());
|
||||
group.setName("dev");
|
||||
group.addPerson(p);
|
||||
final TraversalDescription traversalDescription = new TraversalDescriptionImpl().relationships(DynamicRelationshipType.withName("persons")).evaluator(Evaluators.excludeStartPosition());
|
||||
final TraversalDescription traversalDescription = Traversal.description().relationships(DynamicRelationshipType.withName("persons")).evaluator(Evaluators.excludeStartPosition());
|
||||
Iterable<Person> people = finder.findAllByTraversal(group, traversalDescription);
|
||||
final HashSet<Person> found = new HashSet<Person>();
|
||||
for (Person person : people) {
|
||||
|
||||
@@ -169,7 +169,7 @@ public abstract class AbstractNodeTypeRepresentationStrategyTestBase extends Ent
|
||||
tx.success();
|
||||
return thing;
|
||||
} finally {
|
||||
tx.finish();
|
||||
tx.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -163,7 +163,7 @@ public class IndexBasedRelationshipTypeRepresentationStrategyTests extends Entit
|
||||
link.setLabel("link");
|
||||
tx.success();
|
||||
} finally {
|
||||
tx.finish();
|
||||
tx.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ public class NoopTypeRepresentationStrategyTests extends EntityTestBase {
|
||||
tx.success();
|
||||
return thing;
|
||||
} finally {
|
||||
tx.finish();
|
||||
tx.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.springframework.data.neo4j.aspects.Volvo;
|
||||
import org.springframework.data.neo4j.aspects.support.EntityTestBase;
|
||||
import org.springframework.data.neo4j.core.GraphDatabase;
|
||||
import org.springframework.data.neo4j.repository.GraphRepository;
|
||||
import org.springframework.data.neo4j.support.ReferenceNodes;
|
||||
import org.springframework.data.neo4j.support.mapping.EntityStateHandler;
|
||||
import org.springframework.data.neo4j.support.typerepresentation.SubReferenceNodeTypeRepresentationStrategy;
|
||||
import org.springframework.data.neo4j.template.GraphCallback;
|
||||
@@ -76,6 +77,7 @@ public class SubReferenceNodeTypeRepresentationStrategyTests extends EntityTestB
|
||||
createThing();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void testPostEntityCreation() throws Exception {
|
||||
@@ -87,8 +89,8 @@ public class SubReferenceNodeTypeRepresentationStrategyTests extends EntityTestB
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@Transactional
|
||||
public void gettingTypeFromNonTypeNodeShouldThrowAnDescriptiveException() throws Exception {
|
||||
Node referenceNode = neo4jTemplate.getReferenceNode();
|
||||
nodeTypeRepresentationStrategy.readAliasFrom(referenceNode);
|
||||
Node node = neo4jTemplate.createNode();
|
||||
nodeTypeRepresentationStrategy.readAliasFrom(node);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@@ -110,7 +112,7 @@ public class SubReferenceNodeTypeRepresentationStrategyTests extends EntityTestB
|
||||
subThing.setName("subThing");
|
||||
tx.success();
|
||||
} finally {
|
||||
tx.finish();
|
||||
tx.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ import org.springframework.data.neo4j.fieldaccess.FieldAccessorFactoryFactory;
|
||||
import org.springframework.data.neo4j.mapping.EntityInstantiator;
|
||||
import org.springframework.data.neo4j.support.node.NodeEntityInstantiator;
|
||||
import org.springframework.data.neo4j.support.node.NodeEntityStateFactory;
|
||||
import org.springframework.data.neo4j.transaction.ChainedTransactionManager;
|
||||
import org.springframework.data.transaction.ChainedTransactionManager;
|
||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.jta.JtaTransactionManager;
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
</bean>
|
||||
|
||||
|
||||
<bean id="transactionManager" class="org.springframework.data.neo4j.transaction.ChainedTransactionManager" >
|
||||
<bean id="transactionManager" class="org.springframework.data.transaction.ChainedTransactionManager" >
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="jpaTransactionManager">
|
||||
|
||||
@@ -30,7 +30,7 @@ public class Neo4jDatabaseCleaner {
|
||||
clearIndex(result);
|
||||
tx.success();
|
||||
} finally {
|
||||
tx.finish();
|
||||
tx.close();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public class Neo4jDatabaseCleaner {
|
||||
clearIndex(result);
|
||||
tx.success();
|
||||
} finally {
|
||||
tx.finish();
|
||||
tx.close();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ public class Neo4jDatabaseCleaner {
|
||||
clearIndex(result);
|
||||
tx.success();
|
||||
} finally {
|
||||
tx.finish();
|
||||
tx.close();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ public class PrintNeo4j {
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally {
|
||||
tx.finish();
|
||||
tx.close();
|
||||
}
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<properties>
|
||||
<validation>1.0.0.GA</validation>
|
||||
<jersey.version>1.9</jersey.version>
|
||||
<neo4j-rest-graphdb.version>2.0.0-M06</neo4j-rest-graphdb.version>
|
||||
<neo4j-rest-graphdb.version>2.0.0</neo4j-rest-graphdb.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -38,7 +38,7 @@ import org.springframework.data.neo4j.support.query.QueryEngine;
|
||||
import javax.transaction.TransactionManager;
|
||||
import java.util.Map;
|
||||
|
||||
public class SpringRestGraphDatabase extends org.neo4j.rest.graphdb.RestGraphDatabase implements GraphDatabase{
|
||||
public class SpringRestGraphDatabase extends org.neo4j.rest.graphdb.RestGraphDatabase implements GraphDatabase {
|
||||
static {
|
||||
System.setProperty(Config.CONFIG_BATCH_TRANSACTION,"false");
|
||||
}
|
||||
@@ -189,5 +189,4 @@ public class SpringRestGraphDatabase extends org.neo4j.rest.graphdb.RestGraphDat
|
||||
indexManager.forRelationships(indexName).remove(relationship);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
|
||||
package org.springframework.data.neo4j.rest.integration;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.*;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.data.neo4j.rest.support.RestTestBase;
|
||||
import org.springframework.data.neo4j.unique.UniqueEntityTests;
|
||||
@@ -56,4 +54,34 @@ public class RestUniqueEntityTests extends UniqueEntityTests {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@Ignore("Broken in Neo4j 2.0")
|
||||
@Test
|
||||
public void updatingToADuplicateValueShouldCauseAnException() {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Ignore("Broken in Neo4j 2.0")
|
||||
public void shouldOnlyCreateSingleInstanceForUniqueNodeEntity() {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Ignore("Broken in Neo4j 2.0")
|
||||
public void deletingUniqueNodeShouldRemoveItFromTheUniqueIndex() {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Ignore("Broken in Neo4j 2.0")
|
||||
public void shouldOnlyCreateSingleInstanceForUniqueNumericNodeEntity() {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Ignore("Broken in Neo4j 2.0")
|
||||
public void updatingToANewValueShouldAlsoUpdateTheIndex() {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Ignore("Broken in Neo4j 2.0")
|
||||
public void updatingToANewValueShouldKeepTheEntityUnique() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,17 +45,14 @@ public class Neo4jDatabaseCleaner {
|
||||
}
|
||||
|
||||
private void removeNodes(Map<String, Object> result) {
|
||||
Node refNode = graph.getReferenceNode();
|
||||
int nodes = 0, relationships = 0;
|
||||
for (Node node : graph.getAllNodes()) {
|
||||
for (Relationship rel : node.getRelationships(Direction.OUTGOING)) {
|
||||
rel.delete();
|
||||
relationships++;
|
||||
}
|
||||
if (!refNode.equals(node)) {
|
||||
node.delete();
|
||||
nodes++;
|
||||
}
|
||||
node.delete();
|
||||
nodes++;
|
||||
}
|
||||
result.put("nodes", nodes);
|
||||
result.put("relationships", relationships);
|
||||
|
||||
@@ -32,28 +32,31 @@ public class RestEntityTests extends RestTestBase {
|
||||
|
||||
@Test
|
||||
public void testSetProperty() {
|
||||
restGraphDatabase.getReferenceNode().setProperty( "name", "test" );
|
||||
Node node = restGraphDatabase.getReferenceNode();
|
||||
assertEquals("test", node.getProperty("name"));
|
||||
Node node = restGraphDatabase.createNode();
|
||||
node.setProperty("name", "test");
|
||||
Node node2 = restGraphDatabase.getNodeById(node.getId());
|
||||
assertEquals("test", node2.getProperty("name"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetStringArrayProperty() {
|
||||
restGraphDatabase.getReferenceNode().setProperty( "name", new String[]{"test"} );
|
||||
Node node = restGraphDatabase.getReferenceNode();
|
||||
Assert.assertArrayEquals( new String[]{"test"}, (String[])node.getProperty( "name" ) );
|
||||
Node node = restGraphDatabase.createNode();
|
||||
node.setProperty("name", new String[]{"test"});
|
||||
Node node2 = restGraphDatabase.getNodeById(node.getId());
|
||||
Assert.assertArrayEquals( new String[]{"test"}, (String[])node2.getProperty( "name" ) );
|
||||
}
|
||||
@Test
|
||||
public void testSetDoubleArrayProperty() {
|
||||
double[] data = {0, 1, 2};
|
||||
restGraphDatabase.getReferenceNode().setProperty( "data", data );
|
||||
Node node = restGraphDatabase.getReferenceNode();
|
||||
Assert.assertTrue("same double array",Arrays.equals( data, (double[])node.getProperty( "data" ) ));
|
||||
Node node = restGraphDatabase.createNode();
|
||||
node.setProperty("data", data);
|
||||
Node node2 = restGraphDatabase.getNodeById(node.getId());
|
||||
Assert.assertTrue("same double array",Arrays.equals( data, (double[])node2.getProperty( "data" ) ));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveProperty() {
|
||||
Node node = restGraphDatabase.getReferenceNode();
|
||||
Node node = restGraphDatabase.createNode();
|
||||
node.setProperty( "name", "test" );
|
||||
assertEquals("test", node.getProperty("name"));
|
||||
node.removeProperty( "name" );
|
||||
@@ -72,7 +75,7 @@ public class RestEntityTests extends RestTestBase {
|
||||
|
||||
@Test(expected = NotFoundException.class)
|
||||
public void testRemoveRelationship() {
|
||||
Node refNode = restGraphDatabase.getReferenceNode();
|
||||
Node refNode = restGraphDatabase.createNode();
|
||||
Node node = restGraphDatabase.createNode();
|
||||
Relationship rel = restGraphDatabase.createRelationship(refNode, node, Type.TEST, map("name","test"));
|
||||
final long relId = rel.getId();
|
||||
@@ -84,7 +87,7 @@ public class RestEntityTests extends RestTestBase {
|
||||
|
||||
@Test
|
||||
public void testSetPropertyOnRelationship() {
|
||||
Node refNode = restGraphDatabase.getReferenceNode();
|
||||
Node refNode = restGraphDatabase.createNode();
|
||||
Node node = restGraphDatabase.createNode();
|
||||
Relationship rel = refNode.createRelationshipTo( node, Type.TEST );
|
||||
rel.setProperty( "name", "test" );
|
||||
@@ -95,7 +98,7 @@ public class RestEntityTests extends RestTestBase {
|
||||
|
||||
@Test
|
||||
public void testRemovePropertyOnRelationship() {
|
||||
Node refNode = restGraphDatabase.getReferenceNode();
|
||||
Node refNode = restGraphDatabase.createNode();
|
||||
Node node = restGraphDatabase.createNode();
|
||||
Relationship rel = refNode.createRelationshipTo( node, Type.TEST );
|
||||
rel.setProperty( "name", "test" );
|
||||
|
||||
@@ -26,8 +26,8 @@ public class RestGraphDbTests extends RestTestBase {
|
||||
|
||||
@Test
|
||||
public void testGetRefNode() {
|
||||
Node refNode = restGraphDatabase.getReferenceNode();
|
||||
Node nodeById = restGraphDatabase.getNodeById( 0 );
|
||||
Node refNode = restGraphDatabase.createNode();
|
||||
Node nodeById = restGraphDatabase.getNodeById( refNode.getId() );
|
||||
Assert.assertEquals( refNode, nodeById );
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public class RestGraphDbTests extends RestTestBase {
|
||||
|
||||
@Test
|
||||
public void testCreateRelationship() {
|
||||
Node refNode = restGraphDatabase.getReferenceNode();
|
||||
Node refNode = restGraphDatabase.createNode();
|
||||
Node node = restGraphDatabase.createNode();
|
||||
Relationship rel = refNode.createRelationshipTo( node, Type.TEST );
|
||||
Relationship foundRelationship = IsRelationshipToNodeMatcher.relationshipFromTo( refNode.getRelationships( Type.TEST, Direction.OUTGOING ), refNode, node );
|
||||
@@ -53,7 +53,7 @@ public class RestGraphDbTests extends RestTestBase {
|
||||
|
||||
@Test
|
||||
public void testBasic() {
|
||||
Node refNode = restGraphDatabase.getReferenceNode();
|
||||
Node refNode = restGraphDatabase.createNode();
|
||||
Node node = restGraphDatabase.createNode();
|
||||
Relationship rel = refNode.createRelationshipTo( node,
|
||||
DynamicRelationshipType.withName( "TEST" ) );
|
||||
|
||||
@@ -45,6 +45,7 @@ public class RestTestBase {
|
||||
public static final int PORT = 7470;
|
||||
protected static NeoServer neoServer = null;
|
||||
public static final String SERVER_ROOT_URI = "http://" + HOSTNAME + ":" + PORT + "/db/data/";
|
||||
private Node refNode;
|
||||
|
||||
@BeforeClass
|
||||
public static void startDb() throws Exception {
|
||||
@@ -78,6 +79,7 @@ public class RestTestBase {
|
||||
public void setUp() throws Exception {
|
||||
cleanDb();
|
||||
restGraphDatabase = new SpringRestGraphDatabase(SERVER_ROOT_URI);
|
||||
refNode = restGraphDatabase.createNode();
|
||||
}
|
||||
|
||||
public static void cleanDb() {
|
||||
@@ -102,6 +104,6 @@ public class RestTestBase {
|
||||
}
|
||||
|
||||
protected Node node() {
|
||||
return restGraphDatabase.getReferenceNode();
|
||||
return refNode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ public class RestTestHelper
|
||||
}
|
||||
|
||||
public void cleanDb() {
|
||||
db.cleanContent(true);
|
||||
db.cleanContent();
|
||||
}
|
||||
|
||||
public static void shutdownServer() {
|
||||
|
||||
@@ -1,171 +0,0 @@
|
||||
/**
|
||||
* Copyright 2011-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.data.neo4j.transaction;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.transaction.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
/**
|
||||
* @deprecated use org.springframework.data.transaction.ChainedTransactionManager instead
|
||||
* @author mh
|
||||
* @since 14.02.11
|
||||
*/
|
||||
@Deprecated
|
||||
public class ChainedTransactionManager implements PlatformTransactionManager {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(ChainedTransactionManager.class);
|
||||
|
||||
private final List<PlatformTransactionManager> transactionManagers;
|
||||
private final SynchronizationManager synchronizationManager;
|
||||
|
||||
public ChainedTransactionManager(PlatformTransactionManager... transactionManagers) {
|
||||
this(new DefaultSynchronizationManager(),transactionManagers);
|
||||
}
|
||||
|
||||
public ChainedTransactionManager(SynchronizationManager synchronizationManager, PlatformTransactionManager... transactionManagers) {
|
||||
this.synchronizationManager = synchronizationManager;
|
||||
this.transactionManagers=asList(transactionManagers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiTransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
|
||||
|
||||
MultiTransactionStatus mts = new MultiTransactionStatus(transactionManagers.get(0)/*First TM is main TM*/);
|
||||
|
||||
if (!synchronizationManager.isSynchronizationActive()) {
|
||||
synchronizationManager.initSynchronization();
|
||||
mts.setNewSynchonization();
|
||||
}
|
||||
|
||||
try {
|
||||
for (PlatformTransactionManager transactionManager : transactionManagers) {
|
||||
mts.registerTransactionManager(definition, transactionManager);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Map<PlatformTransactionManager, TransactionStatus> transactionStatuses = mts.getTransactionStatuses();
|
||||
for (PlatformTransactionManager transactionManager : transactionManagers) {
|
||||
try {
|
||||
if (transactionStatuses.get(transactionManager) != null)
|
||||
transactionManager.rollback(transactionStatuses.get(transactionManager));
|
||||
} catch (Exception ex2) {
|
||||
logger.warn("Rollback exception (" + transactionManager + ") " + ex2.getMessage(), ex2);
|
||||
}
|
||||
}
|
||||
|
||||
if (mts.isNewSynchonization()){
|
||||
synchronizationManager.clearSynchronization();
|
||||
}
|
||||
|
||||
throw new CannotCreateTransactionException(ex.getMessage(), ex);
|
||||
}
|
||||
|
||||
return mts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commit(TransactionStatus status) throws TransactionException {
|
||||
|
||||
MultiTransactionStatus multiTransactionStatus = (MultiTransactionStatus) status;
|
||||
|
||||
boolean commit = true;
|
||||
Exception commitException = null;
|
||||
PlatformTransactionManager commitExceptionTransactionManager = null;
|
||||
|
||||
for (PlatformTransactionManager transactionManager : reverse(transactionManagers)) {
|
||||
if (commit) {
|
||||
try {
|
||||
multiTransactionStatus.commit(transactionManager);
|
||||
} catch (Exception ex) {
|
||||
commit = false;
|
||||
commitException = ex;
|
||||
commitExceptionTransactionManager = transactionManager;
|
||||
}
|
||||
} else {
|
||||
//after unsucessfull commit we must try to rollback remaining transaction managers
|
||||
try {
|
||||
multiTransactionStatus.rollback(transactionManager);
|
||||
} catch (Exception ex) {
|
||||
logger.warn("Rollback exception (after commit) (" + transactionManager + ") " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (multiTransactionStatus.isNewSynchonization()){
|
||||
synchronizationManager.clearSynchronization();
|
||||
}
|
||||
|
||||
if (commitException != null) {
|
||||
boolean firstTransactionManagerFailed = commitExceptionTransactionManager == getLastTransactionManager();
|
||||
int transactionState = firstTransactionManagerFailed ? HeuristicCompletionException.STATE_ROLLED_BACK : HeuristicCompletionException.STATE_MIXED;
|
||||
throw new HeuristicCompletionException(transactionState, commitException);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback(TransactionStatus status) throws TransactionException {
|
||||
|
||||
Exception rollbackException = null;
|
||||
PlatformTransactionManager rollbackExceptionTransactionManager = null;
|
||||
|
||||
|
||||
MultiTransactionStatus multiTransactionStatus = (MultiTransactionStatus) status;
|
||||
|
||||
for (PlatformTransactionManager transactionManager : reverse(transactionManagers)) {
|
||||
try {
|
||||
multiTransactionStatus.rollback(transactionManager);
|
||||
} catch (Exception ex) {
|
||||
if (rollbackException == null) {
|
||||
rollbackException = ex;
|
||||
rollbackExceptionTransactionManager = transactionManager;
|
||||
} else {
|
||||
logger.warn("Rollback exception (" + transactionManager + ") " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (multiTransactionStatus.isNewSynchonization()){
|
||||
synchronizationManager.clearSynchronization();
|
||||
}
|
||||
|
||||
if (rollbackException != null) {
|
||||
throw new UnexpectedRollbackException("Rollback exception, originated at ("+rollbackExceptionTransactionManager+") "+
|
||||
rollbackException.getMessage(), rollbackException);
|
||||
}
|
||||
}
|
||||
|
||||
private <T> Iterable<T> reverse(Collection<T> collection) {
|
||||
List<T> list = new ArrayList<T>(collection);
|
||||
Collections.reverse(list);
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
private PlatformTransactionManager getLastTransactionManager() {
|
||||
return transactionManagers.get(lastTransactionManagerIndex());
|
||||
}
|
||||
|
||||
private int lastTransactionManagerIndex() {
|
||||
return transactionManagers.size() - 1;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,11 +19,7 @@ package org.springframework.data.neo4j.transaction;
|
||||
import org.neo4j.helpers.Service;
|
||||
import org.neo4j.kernel.impl.core.KernelPanicEventGenerator;
|
||||
import org.neo4j.kernel.impl.nioneo.store.FileSystemAbstraction;
|
||||
import org.neo4j.kernel.impl.transaction.AbstractTransactionManager;
|
||||
import org.neo4j.kernel.impl.transaction.TransactionManagerProvider;
|
||||
import org.neo4j.kernel.impl.transaction.TransactionStateFactory;
|
||||
import org.neo4j.kernel.impl.transaction.TxHook;
|
||||
import org.neo4j.kernel.impl.transaction.XaDataSourceManager;
|
||||
import org.neo4j.kernel.impl.transaction.*;
|
||||
import org.neo4j.kernel.impl.util.StringLogger;
|
||||
import org.springframework.beans.factory.annotation.Configurable;
|
||||
|
||||
@@ -37,7 +33,13 @@ public class SpringProvider extends TransactionManagerProvider
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractTransactionManager loadTransactionManager(String s, XaDataSourceManager xaDataSourceManager, KernelPanicEventGenerator kernelPanicEventGenerator, TxHook txHook, StringLogger stringLogger, FileSystemAbstraction fileSystemAbstraction, TransactionStateFactory transactionStateFactory) {
|
||||
return new SpringServiceImpl(transactionStateFactory);
|
||||
public AbstractTransactionManager loadTransactionManager( String txLogDir,
|
||||
XaDataSourceManager xaDataSourceManager,
|
||||
KernelPanicEventGenerator kpe,
|
||||
RemoteTxHook rollbackHook,
|
||||
StringLogger msgLog,
|
||||
FileSystemAbstraction fileSystem,
|
||||
TransactionStateFactory stateFactory ) {
|
||||
return new SpringServiceImpl(stateFactory,xaDataSourceManager);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,12 +21,18 @@ import org.neo4j.kernel.api.KernelTransaction;
|
||||
import org.neo4j.kernel.impl.core.TransactionState;
|
||||
import org.neo4j.kernel.impl.transaction.AbstractTransactionManager;
|
||||
import org.neo4j.kernel.impl.transaction.TransactionStateFactory;
|
||||
import org.neo4j.kernel.impl.transaction.XaDataSourceManager;
|
||||
import org.neo4j.kernel.impl.transaction.xaframework.XaDataSource;
|
||||
import org.objectweb.jotm.Current;
|
||||
import org.objectweb.jotm.TransactionResourceManager;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Configurable;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.jta.JtaTransactionManager;
|
||||
|
||||
import javax.transaction.*;
|
||||
import javax.transaction.xa.XAException;
|
||||
import javax.transaction.xa.XAResource;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
@@ -42,13 +48,15 @@ class SpringServiceImpl extends AbstractTransactionManager
|
||||
private TransactionManager delegate;
|
||||
|
||||
private final Map<Transaction, TransactionState> states = new WeakHashMap<Transaction, TransactionState>();
|
||||
private final Map<Transaction, KernelTransaction> kernelTransactions = new WeakHashMap<Transaction, KernelTransaction>();
|
||||
// private final Map<Transaction, KernelTransaction> kernelTransactions = new WeakHashMap<Transaction, KernelTransaction>();
|
||||
private final TransactionStateFactory stateFactory;
|
||||
private XaDataSourceManager xaDataSourceManager;
|
||||
private KernelAPI kernelAPI;
|
||||
|
||||
SpringServiceImpl(TransactionStateFactory stateFactory)
|
||||
SpringServiceImpl(TransactionStateFactory stateFactory, XaDataSourceManager xaDataSourceManager)
|
||||
{
|
||||
this.stateFactory = stateFactory;
|
||||
this.xaDataSourceManager = xaDataSourceManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -61,7 +69,29 @@ class SpringServiceImpl extends AbstractTransactionManager
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doRecovery() throws Throwable {
|
||||
public void doRecovery() throws Throwable
|
||||
{
|
||||
TransactionResourceManager trm = new TransactionResourceManager()
|
||||
{
|
||||
@Override
|
||||
public void returnXAResource( String rmName, XAResource rmXares )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
for ( XaDataSource xaDs : xaDataSourceManager.getAllRegisteredDataSources() )
|
||||
{
|
||||
Current.getTransactionRecovery().registerResourceManager( xaDs.getName(),
|
||||
xaDs.getXaConnection().getXaResource(), xaDs.getName(), trm );
|
||||
}
|
||||
Current.getTransactionRecovery().startResourceManagerRecovery();
|
||||
}
|
||||
catch ( XAException e )
|
||||
{
|
||||
throw new Error( "Error registering xa datasource", e );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -97,7 +127,7 @@ class SpringServiceImpl extends AbstractTransactionManager
|
||||
delegate.begin();
|
||||
Transaction tx = getTransaction();
|
||||
states.put(tx, stateFactory.create(tx));
|
||||
kernelTransactions.put( tx, kernelAPI.newTransaction() );
|
||||
// kernelTransactions.put( tx, kernelAPI.newTransaction() );
|
||||
}
|
||||
|
||||
public void commit() throws RollbackException, HeuristicMixedException,
|
||||
@@ -163,23 +193,23 @@ class SpringServiceImpl extends AbstractTransactionManager
|
||||
this.transactionManager = transactionManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setKernel(KernelAPI kernelAPI) {
|
||||
this.kernelAPI = kernelAPI;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KernelTransaction getKernelTransaction()
|
||||
{
|
||||
Transaction transaction;
|
||||
try
|
||||
{
|
||||
transaction = getTransaction();
|
||||
}
|
||||
catch ( SystemException e )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return kernelTransactions.get( transaction );
|
||||
}
|
||||
// @Override
|
||||
// public void setKernel(KernelAPI kernelAPI) {
|
||||
// this.kernelAPI = kernelAPI;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public KernelTransaction getKernelTransaction()
|
||||
// {
|
||||
// Transaction transaction;
|
||||
// try
|
||||
// {
|
||||
// transaction = getTransaction();
|
||||
// }
|
||||
// catch ( SystemException e )
|
||||
// {
|
||||
// return null;
|
||||
// }
|
||||
// return kernelTransactions.get( transaction );
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -1,307 +0,0 @@
|
||||
/**
|
||||
* 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.transaction;
|
||||
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.Factory;
|
||||
import org.junit.Test;
|
||||
import org.junit.internal.matchers.TypeSafeMatcher;
|
||||
import org.springframework.transaction.*;
|
||||
import org.springframework.transaction.support.DefaultTransactionDefinition;
|
||||
|
||||
import static junit.framework.Assert.*;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.springframework.data.neo4j.transaction.ChainedTransactionManagerTests.TestPlatformTransactionManager.createFailingTransactionManager;
|
||||
import static org.springframework.data.neo4j.transaction.ChainedTransactionManagerTests.TestPlatformTransactionManager.createNonFailingTransactionManager;
|
||||
import static org.springframework.data.neo4j.transaction.ChainedTransactionManagerTests.TransactionManagerMatcher.isCommitted;
|
||||
import static org.springframework.data.neo4j.transaction.ChainedTransactionManagerTests.TransactionManagerMatcher.wasRolledback;
|
||||
import static org.springframework.transaction.HeuristicCompletionException.getStateString;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 15.02.11
|
||||
*/
|
||||
public class ChainedTransactionManagerTests {
|
||||
|
||||
private ChainedTransactionManager tm;
|
||||
|
||||
|
||||
@Test
|
||||
public void shouldCompleteSuccessfully() throws Exception {
|
||||
PlatformTransactionManager transactionManager = createNonFailingTransactionManager("single");
|
||||
setupTransactionManagers(transactionManager);
|
||||
|
||||
createAndCommitTransaction();
|
||||
|
||||
assertThat(transactionManager, isCommitted());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldThrowRolledBackExceptionForSingleTMFailure() throws Exception {
|
||||
|
||||
setupTransactionManagers(createFailingTransactionManager("single"));
|
||||
try
|
||||
{
|
||||
createAndCommitTransaction();
|
||||
fail("Didn't throw the expected exception");
|
||||
} catch (HeuristicCompletionException e){
|
||||
assertEquals(HeuristicCompletionException.STATE_ROLLED_BACK, e.getOutcomeState());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void setupTransactionManagers(PlatformTransactionManager... transactionManagers) {
|
||||
tm = new ChainedTransactionManager(new TestSynchronizationManager(), transactionManagers);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCommitAllRegisteredTM() throws Exception {
|
||||
PlatformTransactionManager first = createNonFailingTransactionManager("first");
|
||||
PlatformTransactionManager second = createNonFailingTransactionManager("second");
|
||||
setupTransactionManagers(first, second);
|
||||
createAndCommitTransaction();
|
||||
assertThat(first, isCommitted());
|
||||
assertThat(second, isCommitted());
|
||||
}
|
||||
@Test
|
||||
public void shouldCommitInReverseOrder() throws Exception {
|
||||
PlatformTransactionManager first = createNonFailingTransactionManager("first");
|
||||
PlatformTransactionManager second = createNonFailingTransactionManager("second");
|
||||
setupTransactionManagers(first, second);
|
||||
createAndCommitTransaction();
|
||||
assertTrue("second tm commited before first ", commitTime(first) >= commitTime(second));
|
||||
|
||||
// assertThat(second, committedBefore(first));
|
||||
}
|
||||
|
||||
private Long commitTime(PlatformTransactionManager transactionManager) {
|
||||
return ((TestPlatformTransactionManager)transactionManager).getCommitTime();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldThrowMixedRolledBackExceptionForNonFirstTMFailure() throws Exception {
|
||||
|
||||
setupTransactionManagers(
|
||||
TestPlatformTransactionManager.createFailingTransactionManager("first"),
|
||||
createNonFailingTransactionManager("second"));
|
||||
try
|
||||
{
|
||||
createAndCommitTransaction();
|
||||
fail("Didn't throw the expected exception");
|
||||
} catch (HeuristicCompletionException e){
|
||||
assertHeuristicException(HeuristicCompletionException.STATE_MIXED, e.getOutcomeState());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRollbackAllTransactionManagers() throws Exception {
|
||||
|
||||
PlatformTransactionManager first = createNonFailingTransactionManager("first");
|
||||
PlatformTransactionManager second = createNonFailingTransactionManager("second");
|
||||
setupTransactionManagers(first, second);
|
||||
createAndRollbackTransaction();
|
||||
assertThat(first, wasRolledback());
|
||||
assertThat(second, wasRolledback());
|
||||
|
||||
}
|
||||
@Test(expected = UnexpectedRollbackException.class )
|
||||
public void shouldThrowExceptionOnFailingRollback() throws Exception {
|
||||
PlatformTransactionManager first = createFailingTransactionManager("first");
|
||||
setupTransactionManagers(first);
|
||||
createAndRollbackTransaction();
|
||||
}
|
||||
|
||||
private void createAndRollbackTransaction() {
|
||||
MultiTransactionStatus transaction = tm.getTransaction(new DefaultTransactionDefinition());
|
||||
tm.rollback(transaction);
|
||||
}
|
||||
|
||||
private void assertHeuristicException(final int expected, final int actual) {
|
||||
assertEquals(getStateString(expected), getStateString(actual));
|
||||
}
|
||||
|
||||
private void createAndCommitTransaction() {
|
||||
MultiTransactionStatus transaction = tm.getTransaction(new DefaultTransactionDefinition());
|
||||
tm.commit(transaction);
|
||||
}
|
||||
|
||||
private static class TestSynchronizationManager implements SynchronizationManager {
|
||||
private boolean synchronizationActive;
|
||||
|
||||
@Override
|
||||
public void initSynchronization() {
|
||||
synchronizationActive=true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSynchronizationActive() {
|
||||
return synchronizationActive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearSynchronization() {
|
||||
synchronizationActive=false;
|
||||
}
|
||||
}
|
||||
|
||||
static class TestPlatformTransactionManager implements PlatformTransactionManager {
|
||||
|
||||
private Long commitTime;
|
||||
private String name;
|
||||
private Long rollbackTime;
|
||||
|
||||
public TestPlatformTransactionManager(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Factory
|
||||
static PlatformTransactionManager createFailingTransactionManager(String name) {
|
||||
return new TestPlatformTransactionManager(name+"-failing")
|
||||
{
|
||||
@Override
|
||||
public void commit(TransactionStatus status) throws TransactionException {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback(TransactionStatus status) throws TransactionException {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Factory
|
||||
static PlatformTransactionManager createNonFailingTransactionManager(String name) {
|
||||
return new TestPlatformTransactionManager(name+"-non-failing");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + (isCommitted() ? " (committed) " : " (not committed)");
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
|
||||
return new TestTransactionStatus(definition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commit(TransactionStatus status) throws TransactionException {
|
||||
commitTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback(TransactionStatus status) throws TransactionException {
|
||||
rollbackTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public boolean isCommitted() {
|
||||
return commitTime!=null;
|
||||
}
|
||||
public boolean wasRolledBack() {
|
||||
return rollbackTime!=null;
|
||||
}
|
||||
|
||||
public Long getCommitTime() {
|
||||
return commitTime;
|
||||
}
|
||||
|
||||
private static class TestTransactionStatus implements TransactionStatus {
|
||||
|
||||
public TestTransactionStatus(TransactionDefinition definition) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNewTransaction() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSavepoint() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRollbackOnly() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRollbackOnly() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompleted() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createSavepoint() throws TransactionException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollbackToSavepoint(Object savepoint) throws TransactionException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseSavepoint(Object savepoint) throws TransactionException {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class TransactionManagerMatcher extends TypeSafeMatcher<PlatformTransactionManager> {
|
||||
private boolean commitCheck;
|
||||
|
||||
public TransactionManagerMatcher(boolean commitCheck) {
|
||||
this.commitCheck = commitCheck;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matchesSafely(PlatformTransactionManager platformTransactionManager) {
|
||||
TestPlatformTransactionManager ptm = (TestPlatformTransactionManager) platformTransactionManager;
|
||||
if (commitCheck) {
|
||||
return ptm.isCommitted();
|
||||
} else {
|
||||
return ptm.wasRolledBack();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
description.appendText("that a "+(commitCheck ? "committed":"rolled-back")+" TransactionManager");
|
||||
}
|
||||
|
||||
@Factory
|
||||
public static TransactionManagerMatcher isCommitted() {
|
||||
return new TransactionManagerMatcher(true);
|
||||
}
|
||||
@Factory
|
||||
public static TransactionManagerMatcher wasRolledback() {
|
||||
return new TransactionManagerMatcher(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,8 @@ import org.neo4j.graphdb.Node;
|
||||
import org.neo4j.graphdb.NotFoundException;
|
||||
import org.neo4j.graphdb.factory.GraphDatabaseSettings;
|
||||
import org.neo4j.kernel.AbstractGraphDatabase;
|
||||
import org.neo4j.kernel.GraphDatabaseAPI;
|
||||
import org.neo4j.kernel.KernelData;
|
||||
import org.neo4j.kernel.configuration.Config;
|
||||
import org.objectweb.jotm.Current;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
@@ -118,20 +120,20 @@ public class JOTMIntegrationTests {
|
||||
nodeId = node.getId();
|
||||
tx.failure();
|
||||
} finally {
|
||||
tx.finish();
|
||||
tx.close();
|
||||
}
|
||||
tx = gds.beginTx();
|
||||
try {
|
||||
gds.getNodeById(nodeId);
|
||||
} finally {
|
||||
tx.success();
|
||||
tx.finish();
|
||||
tx.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void databaseConfiguredWithSpringJtaShouldUseJtaTransactionManager() throws SystemException, NotSupportedException {
|
||||
final Config config = ((AbstractGraphDatabase) gds).getKernelData().getConfig();
|
||||
final Config config = ((GraphDatabaseAPI) gds).getDependencyResolver().resolveDependency(Config.class);
|
||||
Assert.assertEquals("spring-jta", config.getParams().get(GraphDatabaseSettings.tx_manager_impl.name()));
|
||||
|
||||
JtaTransactionManager tm = ctx.getBean("transactionManager", JtaTransactionManager.class);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.data.neo4j.config;
|
||||
|
||||
import org.neo4j.graphdb.Transaction;
|
||||
import org.neo4j.helpers.collection.IteratorUtil;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.event.ContextStartedEvent;
|
||||
@@ -57,7 +58,7 @@ public class ConfigurationCheck implements ApplicationListener<ContextStartedEve
|
||||
private void checkSpringTransactionManager() {
|
||||
try {
|
||||
TransactionStatus transaction = transactionManager.getTransaction(null);
|
||||
updateStartTime();
|
||||
IteratorUtil.count(template.getGraphDatabaseService().getRelationshipTypes());
|
||||
transactionManager.commit(transaction);
|
||||
} catch(Exception e) {
|
||||
throw new BeanCreationException("transactionManager not correctly configured, please refer to the manual, setup section",e);
|
||||
@@ -68,7 +69,8 @@ public class ConfigurationCheck implements ApplicationListener<ContextStartedEve
|
||||
Transaction tx = null;
|
||||
try {
|
||||
tx = template.getGraphDatabase().beginTx();
|
||||
updateStartTime();
|
||||
// read transaction
|
||||
IteratorUtil.count(template.getGraphDatabaseService().getRelationshipTypes());
|
||||
tx.success();
|
||||
} catch (Exception e) {
|
||||
if (tx != null) {
|
||||
@@ -77,14 +79,10 @@ public class ConfigurationCheck implements ApplicationListener<ContextStartedEve
|
||||
throw new BeanCreationException("transactionManager not correctly configured, please refer to the manual, setup section",e);
|
||||
} finally {
|
||||
try {
|
||||
if (tx != null) tx.finish();
|
||||
if (tx != null) tx.close();
|
||||
} catch(Exception e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateStartTime() {
|
||||
template.getReferenceNode().setProperty("startTime", System.currentTimeMillis());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.springframework.core.type.filter.AnnotationTypeFilter;
|
||||
import org.springframework.data.annotation.Persistent;
|
||||
import org.springframework.data.neo4j.annotation.NodeEntity;
|
||||
import org.springframework.data.neo4j.annotation.RelationshipEntity;
|
||||
import org.springframework.data.neo4j.support.GraphDatabaseServiceFactoryBean;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
@@ -143,7 +144,7 @@ public class DataGraphBeanDefinitionParser extends AbstractBeanDefinitionParser
|
||||
String storeDir = element.getAttribute("storeDirectory");
|
||||
if (!hasText(storeDir)) return null;
|
||||
|
||||
BeanDefinitionBuilder graphDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(EmbeddedGraphDatabase.class);
|
||||
BeanDefinitionBuilder graphDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(GraphDatabaseServiceFactoryBean.class);
|
||||
graphDefinitionBuilder.addConstructorArgValue(storeDir);
|
||||
graphDefinitionBuilder.setScope("singleton");
|
||||
graphDefinitionBuilder.setDestroyMethodName("shutdown");
|
||||
|
||||
@@ -101,7 +101,7 @@ public class JtaTransactionManagerFactoryBean implements FactoryBean<JtaTransact
|
||||
|
||||
private UserTransaction createUserTransactionForOnePointSeven( GraphDatabaseService gds ) throws Exception
|
||||
{
|
||||
TransactionManager txManager = ((GraphDatabaseAPI) gds).getTxManager();
|
||||
TransactionManager txManager = ((GraphDatabaseAPI) gds).getDependencyResolver().resolveDependency(TransactionManager.class);
|
||||
return createDynamically( UserTransactionImpl.class, TransactionManager.class, txManager );
|
||||
}
|
||||
|
||||
|
||||
@@ -42,14 +42,7 @@ import org.springframework.data.neo4j.support.Neo4jExceptionTranslator;
|
||||
import org.springframework.data.neo4j.support.Neo4jTemplate;
|
||||
import org.springframework.data.neo4j.support.index.IndexProvider;
|
||||
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;
|
||||
import org.springframework.data.neo4j.support.mapping.TRSTypeAliasAccessor;
|
||||
import org.springframework.data.neo4j.support.mapping.*;
|
||||
import org.springframework.data.neo4j.support.node.NodeEntityInstantiator;
|
||||
import org.springframework.data.neo4j.support.node.NodeEntityStateFactory;
|
||||
import org.springframework.data.neo4j.support.relationship.RelationshipEntityInstantiator;
|
||||
|
||||
@@ -26,15 +26,11 @@ import org.springframework.data.neo4j.support.index.IndexType;
|
||||
import org.springframework.data.neo4j.support.query.QueryEngine;
|
||||
|
||||
import javax.transaction.TransactionManager;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public interface GraphDatabase {
|
||||
/**
|
||||
* @return the reference node of the underlying graph database
|
||||
*/
|
||||
Node getReferenceNode();
|
||||
|
||||
/**
|
||||
* @param id node id
|
||||
* @return the requested node of the underlying graph database
|
||||
@@ -133,4 +129,6 @@ public interface GraphDatabase {
|
||||
Transaction beginTx();
|
||||
|
||||
void shutdown();
|
||||
|
||||
Collection<String> getAllLabelNames();
|
||||
}
|
||||
|
||||
@@ -305,7 +305,7 @@ public class DetachedEntityState<STATE> implements EntityState<STATE> {
|
||||
if (t instanceof RuntimeException) throw (RuntimeException)t;
|
||||
throw new org.springframework.data.neo4j.core.UncategorizedGraphStoreException("Error persisting entity "+getEntity(),t);
|
||||
} finally {
|
||||
tx.finish();
|
||||
tx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.springframework.data.neo4j.support.typerepresentation.LabelBasedNodeT
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.lang.String.format;
|
||||
@@ -95,18 +96,10 @@ public class RelationshipHelper {
|
||||
}
|
||||
|
||||
private Object tryDetermineTypeAssumingLabelBasedStrategy(Relationship relationship,Node node) {
|
||||
|
||||
ResourceIterable<Label> labels = relationship.getOtherNode(node).getLabels();
|
||||
ResourceIterator<Label> iterator = labels.iterator();
|
||||
try {
|
||||
while (iterator.hasNext()) {
|
||||
Label l = iterator.next();
|
||||
if (l.name().startsWith(LabelBasedNodeTypeRepresentationStrategy.LABELSTRATEGY_PREFIX)) {
|
||||
return l.name().substring(LabelBasedNodeTypeRepresentationStrategy.LABELSTRATEGY_PREFIX.length());
|
||||
}
|
||||
for (Label l : relationship.getOtherNode(node).getLabels()) {
|
||||
if (l.name().startsWith(LabelBasedNodeTypeRepresentationStrategy.LABELSTRATEGY_PREFIX)) {
|
||||
return l.name().substring(LabelBasedNodeTypeRepresentationStrategy.LABELSTRATEGY_PREFIX.length());
|
||||
}
|
||||
} finally {
|
||||
iterator.close();
|
||||
}
|
||||
return null;
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.neo4j.index.lucene.ValueContext;
|
||||
import org.neo4j.kernel.GraphDatabaseAPI;
|
||||
import org.neo4j.kernel.Traversal;
|
||||
import org.neo4j.kernel.impl.transaction.SpringTransactionManager;
|
||||
import org.neo4j.tooling.GlobalGraphOperations;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
@@ -45,7 +46,10 @@ import org.springframework.util.ObjectUtils;
|
||||
import javax.transaction.Status;
|
||||
import javax.transaction.SystemException;
|
||||
import javax.transaction.TransactionManager;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
@@ -59,6 +63,7 @@ public class DelegatingGraphDatabase implements GraphDatabase {
|
||||
private ConversionService conversionService;
|
||||
private ResultConverter resultConverter;
|
||||
private volatile QueryEngine<Object> cypherQueryEngine;
|
||||
private long referenceNode = -2;
|
||||
|
||||
public DelegatingGraphDatabase(final GraphDatabaseService delegate) {
|
||||
this(delegate,null);
|
||||
@@ -167,7 +172,7 @@ public class DelegatingGraphDatabase implements GraphDatabase {
|
||||
return (Index<T>) indexManager.forRelationships(indexName, indexConfigFor(indexType));
|
||||
}
|
||||
} finally {
|
||||
tx.success();tx.finish();
|
||||
tx.success();tx.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,7 +238,7 @@ public class DelegatingGraphDatabase implements GraphDatabase {
|
||||
return true; // assume always running tx (e.g. for REST or other remotes)
|
||||
}
|
||||
try {
|
||||
final TransactionManager txManager = ((GraphDatabaseAPI) delegate).getTxManager();
|
||||
final TransactionManager txManager = ((GraphDatabaseAPI) delegate).getDependencyResolver().resolveDependency(TransactionManager.class);
|
||||
return txManager.getStatus() != Status.STATUS_NO_TRANSACTION;
|
||||
} catch (SystemException e) {
|
||||
log.error("Error accessing TransactionManager", e);
|
||||
@@ -279,8 +284,12 @@ public class DelegatingGraphDatabase implements GraphDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node getReferenceNode() {
|
||||
return delegate.getReferenceNode();
|
||||
public Collection<String> getAllLabelNames() {
|
||||
Set<String> labels=new HashSet<>();
|
||||
for (Label label : GlobalGraphOperations.at(delegate).getAllLabels()) {
|
||||
labels.add(label.name());
|
||||
}
|
||||
return labels;
|
||||
}
|
||||
|
||||
public GraphDatabaseService getGraphDatabaseService() {
|
||||
|
||||
@@ -30,7 +30,7 @@ import java.net.URI;
|
||||
* @author mh
|
||||
* @since 25.01.11
|
||||
*/
|
||||
public class GraphDatabaseFactory implements FactoryBean<GraphDatabase> {
|
||||
public class GraphDatabaseFactoryBean implements FactoryBean<GraphDatabase> {
|
||||
|
||||
private String storeLocation;
|
||||
private String userName;
|
||||
@@ -0,0 +1,68 @@
|
||||
package org.springframework.data.neo4j.support;
|
||||
|
||||
import org.neo4j.graphdb.GraphDatabaseService;
|
||||
import org.neo4j.graphdb.factory.GraphDatabaseBuilder;
|
||||
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 04.01.14
|
||||
*/
|
||||
public class GraphDatabaseServiceFactoryBean implements FactoryBean<GraphDatabaseService> {
|
||||
private String path;
|
||||
private Map<String,String> config;
|
||||
private GraphDatabaseService database;
|
||||
|
||||
public GraphDatabaseServiceFactoryBean(String path, Map<String,String> config) {
|
||||
this.path = path;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public GraphDatabaseServiceFactoryBean(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public GraphDatabaseServiceFactoryBean() {
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public void setConfig(Map<String,String> config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphDatabaseService getObject() throws Exception {
|
||||
if (database != null) return database;
|
||||
return database = createDatabase();
|
||||
}
|
||||
|
||||
private GraphDatabaseService createDatabase() {
|
||||
GraphDatabaseBuilder builder = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder(path);
|
||||
if (config != null) {
|
||||
builder.setConfig(config);
|
||||
}
|
||||
return builder.newGraphDatabase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return GraphDatabaseService.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
if (database != null) {
|
||||
database.shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,6 @@ import org.springframework.data.neo4j.mapping.RelationshipResult;
|
||||
import org.springframework.data.neo4j.repository.GraphRepository;
|
||||
import org.springframework.data.neo4j.repository.NodeGraphRepositoryImpl;
|
||||
import org.springframework.data.neo4j.repository.RelationshipGraphRepository;
|
||||
import org.springframework.data.neo4j.support.conversion.EntityResultConverter;
|
||||
import org.springframework.data.neo4j.support.index.IndexProvider;
|
||||
import org.springframework.data.neo4j.support.index.IndexType;
|
||||
import org.springframework.data.neo4j.support.mapping.*;
|
||||
@@ -424,15 +423,6 @@ public class Neo4jTemplate implements Neo4jOperations, ApplicationContextAware {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node getReferenceNode() {
|
||||
try {
|
||||
return infrastructure.getGraphDatabase().getReferenceNode();
|
||||
} catch (RuntimeException e) {
|
||||
throw translateExceptionIfPossible(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node getNode(long id) {
|
||||
if (id < 0) throw new InvalidDataAccessApiUsageException("id is negative");
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
import org.neo4j.cypher.javacompat.ExecutionEngine;
|
||||
import org.neo4j.cypher.javacompat.ExecutionResult;
|
||||
import org.neo4j.graphdb.GraphDatabaseService;
|
||||
import org.neo4j.graphdb.Node;
|
||||
import org.neo4j.helpers.collection.IteratorUtil;
|
||||
import org.springframework.data.neo4j.annotation.QueryType;
|
||||
import org.springframework.data.neo4j.conversion.Result;
|
||||
import org.springframework.data.neo4j.core.GraphDatabase;
|
||||
import org.springframework.data.neo4j.support.query.QueryEngine;
|
||||
|
||||
import static org.neo4j.helpers.collection.MapUtil.map;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 04.01.14
|
||||
*/
|
||||
public class ReferenceNodes {
|
||||
|
||||
public static final String ROOT_NAME = "root";
|
||||
private static ExecutionEngine engine;
|
||||
private static GraphDatabaseService dbRef;
|
||||
|
||||
public static Node getReferenceNode(GraphDatabaseService db) {
|
||||
return getReferenceNode(db, ROOT_NAME);
|
||||
}
|
||||
public static Node getReferenceNode(GraphDatabase db) {
|
||||
return getReferenceNode(db, ROOT_NAME);
|
||||
}
|
||||
public static Node obtainReferenceNode(GraphDatabaseService db) {
|
||||
return obtainReferenceNode(db, ROOT_NAME);
|
||||
}
|
||||
public static Node obtainReferenceNode(GraphDatabase db) {
|
||||
return obtainReferenceNode(db, ROOT_NAME);
|
||||
}
|
||||
|
||||
public static Node obtainReferenceNode(GraphDatabaseService db, String name) {
|
||||
return executeQuery(db, name, "MERGE (ref:ReferenceNode {name:{name}}) RETURN ref");
|
||||
}
|
||||
|
||||
private static Node executeQuery(GraphDatabaseService db, String name, String query) {
|
||||
if (engine == null || db != dbRef) {
|
||||
engine = new ExecutionEngine(db);
|
||||
dbRef = db;
|
||||
}
|
||||
|
||||
ExecutionResult result = engine.execute(query, map("name", name));
|
||||
return IteratorUtil.single(result.<Node>columnAs("ref"));
|
||||
}
|
||||
|
||||
public static Node getReferenceNode(GraphDatabaseService db, String name) {
|
||||
return executeQuery(db, name, "MATCH (ref:ReferenceNode {name:{name}}) RETURN ref");
|
||||
}
|
||||
|
||||
public static Node obtainReferenceNode(GraphDatabase db, String name) {
|
||||
return executeQuery(db, name, "MERGE (ref:ReferenceNode {name:{name}}) RETURN ref");
|
||||
}
|
||||
|
||||
private static Node executeQuery(GraphDatabase db, String name, String query) {
|
||||
QueryEngine<Result> engine = db.queryEngineFor(QueryType.Cypher);
|
||||
return engine.query(query,map("name", name)).to(Node.class).singleOrNull();
|
||||
}
|
||||
|
||||
public static Node getReferenceNode(GraphDatabase db, String name) {
|
||||
return executeQuery(db, name, "MATCH (ref:ReferenceNode {name:{name}}) RETURN ref");
|
||||
}
|
||||
}
|
||||
@@ -37,75 +37,50 @@ public class ResultColumnValueExtractor {
|
||||
NoSuchMethodException,
|
||||
IllegalAccessException,
|
||||
InvocationTargetException {
|
||||
ResultColumn column = field.getAnnotation(ResultColumn.class);
|
||||
TypeInformation<?> classInfo = ClassTypeInformation.from(field.getDeclaringClass());
|
||||
TypeInformation<?> fieldInfo = classInfo.getProperty(field.getName());
|
||||
return extractFromAccessibleObject(column,fieldInfo);
|
||||
return extractFromAccessibleObject(fieldInfo, columnNameFor(field));
|
||||
}
|
||||
|
||||
private String columnNameFor(Field field) {
|
||||
ResultColumn column = field.getAnnotation(ResultColumn.class);
|
||||
if (column != null) return column.value();
|
||||
return field.getName();
|
||||
}
|
||||
|
||||
public Object extractFromMethod(Method method) throws ClassNotFoundException,
|
||||
NoSuchMethodException,
|
||||
IllegalAccessException,
|
||||
InvocationTargetException {
|
||||
ResultColumn column = method.getAnnotation(ResultColumn.class);
|
||||
TypeInformation<?> returnType = ClassTypeInformation.fromReturnTypeOf(method);
|
||||
return extractFromAccessibleObject(column,returnType);
|
||||
return extractFromAccessibleObject(returnType, columnNameFor(method));
|
||||
}
|
||||
|
||||
public Object extractFromAccessibleObject(ResultColumn column, TypeInformation<?> returnType)
|
||||
private String columnNameFor(Method method) {
|
||||
ResultColumn column = method.getAnnotation(ResultColumn.class);
|
||||
if (column != null) return column.value();
|
||||
String name = method.getName();
|
||||
if (name.startsWith("get")) name = name.substring(3);
|
||||
return Character.toLowerCase(name.charAt(0)) + name.substring(1);
|
||||
}
|
||||
|
||||
public Object extractFromAccessibleObject(TypeInformation<?> returnType, String columnName)
|
||||
throws ClassNotFoundException,
|
||||
NoSuchMethodException,
|
||||
IllegalAccessException,
|
||||
InvocationTargetException {
|
||||
|
||||
String columnName = column.value();
|
||||
if(!map.containsKey( columnName )) {
|
||||
throw new NoSuchColumnFoundException( columnName );
|
||||
if(!map.containsKey(columnName)) {
|
||||
throw new NoSuchColumnFoundException(columnName);
|
||||
}
|
||||
|
||||
Object columnValue = map.get(columnName);
|
||||
if(columnValue==null) return null;
|
||||
|
||||
// If the returned value is a Scala iterable, transform it to a Java iterable first
|
||||
Class iterableLikeInterface = implementsInterface("scala.collection.Iterable", columnValue.getClass());
|
||||
if (iterableLikeInterface!=null) {
|
||||
columnValue = transformScalaIterableToJavaIterable(columnValue, iterableLikeInterface);
|
||||
}
|
||||
|
||||
if (returnType.isCollectionLike()) {
|
||||
QueryResultBuilder qrb = new QueryResultBuilder((Iterable)columnValue, converter);
|
||||
return qrb.to(returnType.getActualType().getType());
|
||||
return qrb.to(returnType.getActualType().getType()).as(returnType.getType());
|
||||
} else
|
||||
return converter.convert(columnValue, returnType.getType(), mappingPolicy);
|
||||
}
|
||||
|
||||
|
||||
public Object transformScalaIterableToJavaIterable(Object scalaIterable, Class iterableLikeIface) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||
// This is equivalent to doing this:
|
||||
// JavaConversions.asJavaIterable(((IterableLike) columnValue).toIterable());
|
||||
|
||||
Class<?> javaConversions = iterableLikeIface.getClassLoader().loadClass("scala.collection.JavaConversions");
|
||||
Method asJavaIterable = javaConversions.getMethod("asJavaIterable", iterableLikeIface);
|
||||
Iterable<?> javaIterable = (Iterable<?>) asJavaIterable.invoke(null, scalaIterable);
|
||||
return javaIterable;
|
||||
}
|
||||
|
||||
private Class implementsInterface(String interfaceName, Class clazz) {
|
||||
if(clazz.getCanonicalName().equals(interfaceName)) return clazz;
|
||||
|
||||
Class superclass = clazz.getSuperclass();
|
||||
if(superclass != null) {
|
||||
Class iface = implementsInterface(interfaceName, superclass);
|
||||
if (iface!= null) return iface;
|
||||
}
|
||||
|
||||
for(Class iface : clazz.getInterfaces()) {
|
||||
Class superIface = implementsInterface(interfaceName, iface);
|
||||
if(superIface!=null)
|
||||
return superIface;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ public class SourceStateTransmitter<S extends PropertyContainer> {
|
||||
if (t instanceof RuntimeException) throw (RuntimeException)t;
|
||||
throw new org.springframework.data.neo4j.core.UncategorizedGraphStoreException("Error copying properties from "+persistentEntity+" to "+target,t);
|
||||
} finally {
|
||||
tx.finish();
|
||||
tx.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ public abstract class Neo4jHelper {
|
||||
tx.failure();
|
||||
throw new org.springframework.data.neo4j.core.UncategorizedGraphStoreException("Error cleaning database ",t);
|
||||
} finally {
|
||||
tx.finish();
|
||||
tx.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,12 +92,10 @@ public abstract class Neo4jHelper {
|
||||
}
|
||||
}
|
||||
for (Node node : globalGraphOperations.getAllNodes()) {
|
||||
if (includeReferenceNode || !graphDatabaseService.getReferenceNode().equals(node)) {
|
||||
try {
|
||||
node.delete();
|
||||
} catch(IllegalStateException ise) {
|
||||
if (!ise.getMessage().contains("since it has already been deleted")) throw ise;
|
||||
}
|
||||
try {
|
||||
node.delete();
|
||||
} catch(IllegalStateException ise) {
|
||||
if (!ise.getMessage().contains("since it has already been deleted")) throw ise;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,10 +24,14 @@ import org.springframework.data.neo4j.annotation.QueryType;
|
||||
import org.springframework.data.neo4j.core.GraphDatabase;
|
||||
import org.springframework.data.neo4j.core.NodeTypeRepresentationStrategy;
|
||||
import org.springframework.data.neo4j.repository.query.CypherQuery;
|
||||
import org.springframework.data.neo4j.support.ReferenceNodes;
|
||||
import org.springframework.data.neo4j.support.mapping.StoredEntityType;
|
||||
import org.springframework.data.neo4j.support.mapping.WrappedIterableClosableIterable;
|
||||
import org.springframework.data.neo4j.support.query.QueryEngine;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Provides a Node Type Representation Strategy which makes use of Labels, and specifically
|
||||
* uses Cypher as the mechanism for interacting with the graph database.
|
||||
@@ -37,9 +41,8 @@ import org.springframework.data.neo4j.support.query.QueryEngine;
|
||||
*/
|
||||
public class LabelBasedNodeTypeRepresentationStrategy implements NodeTypeRepresentationStrategy {
|
||||
|
||||
public static final Label SDN_LABEL_STRATEGY = DynamicLabel.label("SDN_LABEL_STRATEGY");
|
||||
public static final String SDN_LABEL_STRATEGY = "SDN_LABEL_STRATEGY";
|
||||
public static final String LABELSTRATEGY_PREFIX = "__TYPE__";
|
||||
public static final long REFERENCE_NODE_ID = 0L;
|
||||
|
||||
protected GraphDatabase graphDb;
|
||||
protected final Class<Node> clazz;
|
||||
@@ -62,7 +65,7 @@ public class LabelBasedNodeTypeRepresentationStrategy implements NodeTypeReprese
|
||||
if (state.hasLabel(sdnLabel)) {
|
||||
return; // already there
|
||||
}
|
||||
addLabelsForEntityHierarchy(state,type);
|
||||
addLabelsForEntityHierarchy(state, type);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,33 +75,36 @@ public class LabelBasedNodeTypeRepresentationStrategy implements NodeTypeReprese
|
||||
* as the primary SDN marker Label.
|
||||
*/
|
||||
private void addLabelsForEntityHierarchy(Node state, StoredEntityType type) {
|
||||
String labels = cypherHelper.buildLabelString(LABELSTRATEGY_PREFIX + type.getAlias(), (String)type.getAlias());
|
||||
labels = buildLabelStringIncludingEachEntityInHierarchy(labels, type);
|
||||
String alias = type.getAlias().toString();
|
||||
Set<String> labels = collectSuperTypeLabels(type, new HashSet<String>());
|
||||
labels.add(alias);
|
||||
labels.add(LABELSTRATEGY_PREFIX + alias);
|
||||
cypherHelper.setLabelsOnNode(state.getId(), labels);
|
||||
}
|
||||
|
||||
private String buildLabelStringIncludingEachEntityInHierarchy(String labels, StoredEntityType type) {
|
||||
private Set<String> collectSuperTypeLabels(StoredEntityType type, Set<String> labels) {
|
||||
if (type==null) return labels;
|
||||
for (StoredEntityType superType : type.getSuperTypes()) {
|
||||
labels += cypherHelper.buildLabelString((String)superType.getAlias());
|
||||
labels += buildLabelStringIncludingEachEntityInHierarchy(labels, superType);
|
||||
labels.add(superType.getAlias().toString());
|
||||
collectSuperTypeLabels(superType, labels);
|
||||
}
|
||||
return labels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that a special label (SDN_LABEL_STRATEGY) exists against the
|
||||
* reference node, and if it does not, it is added. This label serves
|
||||
* Ensures that a special label (SDN_LABEL_STRATEGY) exists in the graph,
|
||||
* and if it does not, it is added. This label serves
|
||||
* as an indicator that the Labeling strategy has/is going to be used on this
|
||||
* data set.
|
||||
*/
|
||||
private void markSDNLabelStrategyInUse() {
|
||||
cypherHelper.setLabelOnNode(REFERENCE_NODE_ID, SDN_LABEL_STRATEGY.name());
|
||||
cypherHelper.createMarkerLabel(SDN_LABEL_STRATEGY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U> ClosableIterable<Node> findAll(StoredEntityType type) {
|
||||
Iterable<Node> rin = cypherHelper.getNodesWithLabel(type.getAlias().toString());
|
||||
return new WrappedIterableClosableIterable<Node>(rin);
|
||||
return new WrappedIterableClosableIterable<>(rin);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -122,11 +128,9 @@ public class LabelBasedNodeTypeRepresentationStrategy implements NodeTypeReprese
|
||||
|
||||
@Override
|
||||
public void preEntityRemoval(Node state) {
|
||||
// don't think we need to do anything here!
|
||||
}
|
||||
|
||||
public static boolean isStrategyAlreadyInUse(GraphDatabase graphDatabaseService) {
|
||||
return graphDatabaseService.getReferenceNode().hasLabel(SDN_LABEL_STRATEGY);
|
||||
|
||||
return graphDatabaseService.getAllLabelNames().contains(SDN_LABEL_STRATEGY);
|
||||
}
|
||||
}
|
||||
@@ -5,9 +5,9 @@ import org.springframework.data.neo4j.conversion.Result;
|
||||
import org.springframework.data.neo4j.repository.query.CypherQuery;
|
||||
import org.springframework.data.neo4j.support.query.QueryEngine;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
import static org.neo4j.helpers.collection.Iterables.join;
|
||||
|
||||
/**
|
||||
* Provides some helper Cypher based functionality specifically
|
||||
@@ -22,6 +22,7 @@ import java.util.Map;
|
||||
public class LabelBasedStrategyCypherHelper {
|
||||
|
||||
static final String CYPHER_ADD_LABEL_TO_NODE = "match (n) where id(n)={nodeId} set n:`%s`";
|
||||
static final String CYPHER_CREATE_MARKER_LABEL = "match (n) with n limit 1 set n:`%1$s` remove n:`%1$s` return count(*)";
|
||||
static final String CYPHER_ADD_LABELS_TO_NODE = "match (n) where id(n)={nodeId} set n%s";
|
||||
static final String CYPHER_COUNT_LABELS_ON_NODE = "match (n) where id(n)={nodeId} and n:`%s` return count(*) ";
|
||||
static final String CYPHER_RETURN_NODES_WITH_LABEL = "match (n:`%s`) return n";
|
||||
@@ -39,11 +40,20 @@ public class LabelBasedStrategyCypherHelper {
|
||||
queryEngine.query( addLabelStatement, getParamsWithNodeId(nodeId) );
|
||||
}
|
||||
|
||||
public void setLabelsOnNode(Long nodeId, String labelString) {
|
||||
String addLabelStatement = String.format(CYPHER_ADD_LABELS_TO_NODE , labelString);
|
||||
public void createMarkerLabel(String label) {
|
||||
String addLabelStatement = String.format(CYPHER_CREATE_MARKER_LABEL , label);
|
||||
queryEngine.query( addLabelStatement, null );
|
||||
}
|
||||
|
||||
public void setLabelsOnNode(Long nodeId, Collection<String> labelString) {
|
||||
String addLabelStatement = formatAddLabelString(labelString);
|
||||
queryEngine.query( addLabelStatement, getParamsWithNodeId(nodeId) );
|
||||
}
|
||||
|
||||
private String formatAddLabelString(Collection<String> labels) {
|
||||
return String.format(CYPHER_ADD_LABELS_TO_NODE,":`"+join("`:`",labels)+"`");
|
||||
}
|
||||
|
||||
public boolean doesNodeHaveLabel(Long nodeId, String label) {
|
||||
String query = String.format(CYPHER_COUNT_LABELS_ON_NODE, label);
|
||||
Result<CypherQuery> result = queryEngine.query(query, getParamsWithNodeId(nodeId));
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.neo4j.core.GraphDatabase;
|
||||
import org.springframework.data.neo4j.core.NodeTypeRepresentationStrategy;
|
||||
import org.springframework.data.neo4j.support.ReferenceNodes;
|
||||
import org.springframework.data.neo4j.support.mapping.StoredEntityType;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -49,12 +50,14 @@ public class SubReferenceNodeTypeRepresentationStrategy implements NodeTypeRepre
|
||||
public static final String SUBREFERENCE_NODE_COUNTER_KEY = "count";
|
||||
public static final String SUBREF_PREFIX = "SUBREF_";
|
||||
public static final String SUBREF_CLASS_KEY = "class";
|
||||
private long referenceNodeId;
|
||||
|
||||
private GraphDatabase graphDatabase;
|
||||
private GraphDatabase graphDatabase;
|
||||
private final EntityTypeCache typeCache;
|
||||
|
||||
public SubReferenceNodeTypeRepresentationStrategy(GraphDatabase graphDatabase) {
|
||||
this.graphDatabase = graphDatabase;
|
||||
this.referenceNodeId = ReferenceNodes.obtainReferenceNode(graphDatabase,"root").getId();
|
||||
typeCache = new EntityTypeCache();
|
||||
}
|
||||
|
||||
@@ -89,7 +92,9 @@ public class SubReferenceNodeTypeRepresentationStrategy implements NodeTypeRepre
|
||||
|
||||
public static boolean isStrategyAlreadyInUse(GraphDatabase graphDatabaseService) {
|
||||
try {
|
||||
for (Relationship rel : graphDatabaseService.getReferenceNode().getRelationships()) {
|
||||
Node referenceNode = ReferenceNodes.getReferenceNode(graphDatabaseService,"root");
|
||||
if (referenceNode==null) return false;
|
||||
for (Relationship rel : referenceNode.getRelationships()) {
|
||||
if (rel.getType().name().startsWith(SubReferenceNodeTypeRepresentationStrategy.SUBREF_PREFIX)) {
|
||||
return true;
|
||||
}
|
||||
@@ -206,7 +211,7 @@ public class SubReferenceNodeTypeRepresentationStrategy implements NodeTypeRepre
|
||||
return findSubreferenceNode(type.getAlias());
|
||||
}
|
||||
public Node findSubreferenceNode(final Object alias) {
|
||||
final Relationship subrefRelationship = graphDatabase.getReferenceNode().getSingleRelationship(subRefRelationshipType(alias), Direction.OUTGOING);
|
||||
final Relationship subrefRelationship = referenceNode().getSingleRelationship(subRefRelationshipType(alias), Direction.OUTGOING);
|
||||
return subrefRelationship != null ? subrefRelationship.getEndNode() : null;
|
||||
}
|
||||
|
||||
@@ -218,10 +223,20 @@ public class SubReferenceNodeTypeRepresentationStrategy implements NodeTypeRepre
|
||||
}
|
||||
|
||||
public Node getOrCreateSubReferenceNode(final RelationshipType relType) {
|
||||
return getOrCreateSingleOtherNode(graphDatabase.getReferenceNode(), relType, Direction.OUTGOING);
|
||||
return getOrCreateSingleOtherNode(referenceNode(), relType, Direction.OUTGOING);
|
||||
}
|
||||
|
||||
private Node getOrCreateSingleOtherNode(Node fromNode, RelationshipType type,
|
||||
private Node referenceNode() {
|
||||
try {
|
||||
return graphDatabase.getNodeById(referenceNodeId);
|
||||
} catch (NotFoundException nfe) {
|
||||
Node node = ReferenceNodes.obtainReferenceNode(graphDatabase, "root");
|
||||
referenceNodeId = node.getId();
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
private Node getOrCreateSingleOtherNode(Node fromNode, RelationshipType type,
|
||||
Direction direction) {
|
||||
Relationship singleRelationship = fromNode.getSingleRelationship(type, direction);
|
||||
if (singleRelationship != null) {
|
||||
|
||||
@@ -55,11 +55,6 @@ public interface Neo4jOperations {
|
||||
|
||||
<T> GraphRepository<T> repositoryFor(Class<T> clazz);
|
||||
|
||||
/**
|
||||
* Returns the reference node.
|
||||
*/
|
||||
Node getReferenceNode();
|
||||
|
||||
/**
|
||||
* Delegates to the GraphDatabase
|
||||
*
|
||||
|
||||
@@ -82,15 +82,15 @@ public class DataGraphNamespaceHandlerTests {
|
||||
final Config config = assertInjected("-external-embedded");
|
||||
final GraphDatabaseAPI gds = (GraphDatabaseAPI) config.graphDatabaseService;
|
||||
assertEquals(EmbeddedGraphDatabase.class, gds.getClass());
|
||||
final org.neo4j.kernel.configuration.Config neoConfig = gds.getKernelData().getConfig();
|
||||
final org.neo4j.kernel.configuration.Config neoConfig = gds.getDependencyResolver().resolveDependency(org.neo4j.kernel.configuration.Config.class);
|
||||
assertEquals("true", neoConfig.getParams().get("allow_store_upgrade"));
|
||||
}
|
||||
@Test
|
||||
@Ignore("todo setup zk-cluster")
|
||||
public void injectionForExistingHighlyAvailableGraphDatabaseService() {
|
||||
final Config config = assertInjected("-external-ha");
|
||||
final AbstractGraphDatabase gds = (AbstractGraphDatabase) config.graphDatabaseService;
|
||||
final org.neo4j.kernel.configuration.Config neoConfig = gds.getKernelData().getConfig();
|
||||
final GraphDatabaseAPI gds = (GraphDatabaseAPI) config.graphDatabaseService;
|
||||
final org.neo4j.kernel.configuration.Config neoConfig = gds.getDependencyResolver().resolveDependency(org.neo4j.kernel.configuration.Config.class);
|
||||
assertEquals("HighlyAvailableGraphDatabase", gds.getClass().getSimpleName());
|
||||
assertEquals("1", neoConfig.getParams().get("ha.server_id"));
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ public class Neo4jEntityPersisterTests extends Neo4jPersistentTestBase {
|
||||
@Test
|
||||
@Transactional
|
||||
public void testFetchSingleEntity() {
|
||||
final Node node = template.getReferenceNode();
|
||||
final Node node = template.createNode();
|
||||
node.setProperty("name","Fetch");
|
||||
final Person p = new Person(node.getId());
|
||||
template.fetch(p);
|
||||
@@ -100,7 +100,7 @@ public class Neo4jEntityPersisterTests extends Neo4jPersistentTestBase {
|
||||
@Test
|
||||
@Transactional
|
||||
public void testFetchEntityCollection() {
|
||||
final Node node = template.getReferenceNode();
|
||||
final Node node = template.createNode();
|
||||
node.setProperty("name","Fetch");
|
||||
final Person p = new Person(node.getId());
|
||||
template.fetch(asList(p));
|
||||
|
||||
@@ -159,7 +159,7 @@ public class Neo4jPersistentTestBase {
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
tx.failure();
|
||||
tx.finish();
|
||||
tx.close();
|
||||
template.getGraphDatabaseService().shutdown();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ import org.neo4j.graphdb.DynamicRelationshipType;
|
||||
import org.neo4j.graphdb.traversal.Evaluators;
|
||||
import org.neo4j.graphdb.traversal.TraversalDescription;
|
||||
import org.neo4j.kernel.Traversal;
|
||||
import org.neo4j.kernel.impl.traversal.TraversalDescriptionImpl;
|
||||
import org.springframework.data.neo4j.annotation.Fetch;
|
||||
import org.springframework.data.neo4j.annotation.GraphId;
|
||||
import org.springframework.data.neo4j.annotation.GraphProperty;
|
||||
@@ -162,7 +161,7 @@ public class Group implements IGroup , Serializable {
|
||||
@Override
|
||||
public TraversalDescription build(Object start, Neo4jPersistentProperty property, String... params) {
|
||||
//return new TraversalDescriptionImpl().relationships(DynamicRelationshipType.withName(params[0])).filter(Traversal.returnAllButStartNode());
|
||||
return new TraversalDescriptionImpl().relationships(DynamicRelationshipType.withName(params[0])).evaluator(Evaluators.excludeStartPosition());
|
||||
return Traversal.description().relationships(DynamicRelationshipType.withName(params[0])).evaluator(Evaluators.excludeStartPosition());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.neo4j.graphdb.GraphDatabaseService;
|
||||
import org.neo4j.graphdb.Node;
|
||||
import org.neo4j.graphdb.Transaction;
|
||||
import org.neo4j.helpers.collection.IteratorUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -32,9 +31,9 @@ import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.neo4j.model.*;
|
||||
import org.springframework.data.neo4j.support.Neo4jTemplate;
|
||||
import org.springframework.data.neo4j.support.ReferenceNodes;
|
||||
import org.springframework.data.neo4j.support.conversion.NoSuchColumnFoundException;
|
||||
import org.springframework.data.neo4j.support.node.Neo4jHelper;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.CleanContextCacheTestExecutionListener;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
@@ -211,6 +210,14 @@ public class GraphRepositoryTests {
|
||||
assertThat( asCollection( teamMembers ), hasItems( testTeam.michael, testTeam.david, testTeam.emil ) );
|
||||
}
|
||||
|
||||
|
||||
@Test @Transactional
|
||||
public void testFindQueryResultWithCollection() {
|
||||
PersonRepository.TeamResult teamMembers = personRepository.findAllTeamMembersAsGroup(testTeam.sdg);
|
||||
assertThat( teamMembers.getName(), is( testTeam.sdg.getName() ) );
|
||||
assertThat( asCollection( teamMembers.getMembers() ), hasItems( testTeam.michael, testTeam.david, testTeam.emil ) );
|
||||
}
|
||||
|
||||
@Test @Transactional
|
||||
public void testFindIterableOfPersonWithQueryAnnotationSpatial() {
|
||||
Iterable<Person> teamMembers = personRepository.findWithinBoundingBox("personLayer", 55, 15, 57, 17);
|
||||
@@ -273,7 +280,7 @@ public class GraphRepositoryTests {
|
||||
}
|
||||
|
||||
@Test @Transactional
|
||||
@Ignore("cypher bug with escaped params")
|
||||
// @Ignore("cypher bug with escaped params")
|
||||
public void testFindWithMultipleParameters() {
|
||||
final int depth = 1;
|
||||
final int limit = 2;
|
||||
@@ -438,7 +445,7 @@ public class GraphRepositoryTests {
|
||||
|
||||
@Test @Transactional
|
||||
public void testConnectToRootEntity() {
|
||||
final Node referenceNode = neo4jTemplate.getReferenceNode();
|
||||
final Node referenceNode = ReferenceNodes.obtainReferenceNode(gdb,"root");
|
||||
neo4jTemplate.postEntityCreation(referenceNode,RootEntity.class);
|
||||
final RootEntity root = neo4jTemplate.findOne(referenceNode.getId(), RootEntity.class);
|
||||
root.setRootName("RootName");
|
||||
|
||||
@@ -89,7 +89,7 @@ public class NoIndexDerivedFinderTests {
|
||||
final Index<Node> index = gdb.index().forNodes("Test");
|
||||
assertEquals("Test", gdb.index().nodeIndexNames()[0]);
|
||||
tx.success();
|
||||
tx.finish();
|
||||
tx.close();
|
||||
}
|
||||
};
|
||||
t.start();t.join();
|
||||
@@ -99,7 +99,7 @@ public class NoIndexDerivedFinderTests {
|
||||
assertEquals(0,IteratorUtil.count(result));
|
||||
assertEquals("Test", gdb.index().nodeIndexNames()[0]);
|
||||
} finally {
|
||||
tx.success();tx.finish();
|
||||
tx.success();tx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.springframework.data.neo4j.model.Person;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -43,16 +44,19 @@ public interface PersonRepository extends GraphRepository<Person>, NamedIndexRep
|
||||
@Query("start team=node({p_team}) match (team)-[:persons]->(member) return member")
|
||||
Iterable<Person> findAllTeamMembers(@Param("p_team") Group team);
|
||||
|
||||
@Query("start team=node({p_team}) match (team)-[:persons]->(member) return team.name as name,collect(member) as members")
|
||||
TeamResult findAllTeamMembersAsGroup(@Param("p_team") Group team);
|
||||
|
||||
@Query("start team=node({p_team}) match (team)-[:persons]->(member) return member.name,member.age")
|
||||
Iterable<Map<String, Object>> findAllTeamMemberData(@Param("p_team") Group team);
|
||||
|
||||
@Query("start member=node({p_person}) match team-[:persons]->member<-[?:boss]-boss return collect(team), boss")
|
||||
@Query("start member=node({p_person}) match team-[:persons]->member<-[:boss]-boss return collect(team), boss")
|
||||
Iterable<MemberData> findMemberData(@Param("p_person") Person person);
|
||||
|
||||
@Query("start member=node({p_person}) match team-[:persons]->member<-[?:boss]-boss return collect(team), boss, boss.name as someonesName, boss.age as someonesAge ")
|
||||
@Query("start member=node({p_person}) match team-[:persons]->member<-[:boss]-boss return collect(team), boss, boss.name as someonesName, boss.age as someonesAge ")
|
||||
MemberDataPOJO findMemberDataPojo(@Param("p_person") Person person);
|
||||
|
||||
@Query("start member=node({p_person}) match team-[:persons]->member<-[?:boss]-boss return member")
|
||||
@Query("start member=node({p_person}) match team-[:persons]->member<-[:boss]-boss return member")
|
||||
Iterable<MemberData> nonWorkingQuery(@Param("p_person") Person person);
|
||||
|
||||
@Query("start team=node:Group(name = {p_team}) match (team)-[:persons*1..1]->(member) return member order by member.name skip {`skip`} limit {`limit`}")
|
||||
@@ -102,5 +106,13 @@ public interface PersonRepository extends GraphRepository<Person>, NamedIndexRep
|
||||
@ResultColumn("person")
|
||||
Person getPerson();
|
||||
}
|
||||
@QueryResult
|
||||
interface TeamResult
|
||||
{
|
||||
String getName();
|
||||
|
||||
@ResultColumn("members")
|
||||
Collection<Person> getMembers();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ public class ReadWriteTests {
|
||||
Volvo volvo = template.save(new Volvo());
|
||||
assertEquals(1, volvo.id.intValue());
|
||||
tx.success();
|
||||
tx.finish();
|
||||
tx.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
@@ -20,7 +20,7 @@ import javax.enterprise.inject.Disposes;
|
||||
import javax.enterprise.inject.Produces;
|
||||
|
||||
import org.springframework.data.neo4j.core.GraphDatabase;
|
||||
import org.springframework.data.neo4j.support.GraphDatabaseFactory;
|
||||
import org.springframework.data.neo4j.support.GraphDatabaseFactoryBean;
|
||||
|
||||
/**
|
||||
* Simple component exposing a {@link GraphDatabase} as CDI bean.
|
||||
@@ -34,7 +34,7 @@ class Neo4jCdiProducer {
|
||||
@ApplicationScoped
|
||||
GraphDatabase createGraphDatabase() throws Exception {
|
||||
|
||||
GraphDatabaseFactory factory = new GraphDatabaseFactory();
|
||||
GraphDatabaseFactoryBean factory = new GraphDatabaseFactoryBean();
|
||||
factory.setStoreLocation("target/cdi-test-db");
|
||||
|
||||
return factory.getObject();
|
||||
|
||||
@@ -418,7 +418,9 @@ public abstract class AbstractDerivedFinderMethodTestBase {
|
||||
String query = derivedCypherRepositoryQuery.createQueryWithPagingAndSorting(accessor);
|
||||
Map<String, Object> params = derivedCypherRepositoryQuery.resolveParams(accessor);
|
||||
String firstWord = expectedQuery.split("\\s+")[0];
|
||||
assertEquals(expectedQuery,query.substring(query.indexOf(firstWord)).substring(0,expectedQuery.length()));
|
||||
String actual = query.substring(query.indexOf(firstWord));
|
||||
actual = actual.substring(0, Math.min(expectedQuery.length(),actual.length()));
|
||||
assertEquals(expectedQuery, actual);
|
||||
assertEquals(expectedParam.length,params.size());
|
||||
for (int i = 0; i < expectedParam.length; i++) {
|
||||
if (expectedParam[i] instanceof ValueContext) {
|
||||
|
||||
@@ -91,7 +91,7 @@ public class EntityTestBase {
|
||||
cleanDb();
|
||||
tx.success();
|
||||
} finally {
|
||||
tx.finish();
|
||||
tx.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ public class GraphDatabaseFactoryTests {
|
||||
}
|
||||
@Test
|
||||
public void shouldCreateLocalDatabase() throws Exception {
|
||||
GraphDatabaseFactory factory = new GraphDatabaseFactory();
|
||||
GraphDatabaseFactoryBean factory = new GraphDatabaseFactoryBean();
|
||||
try {
|
||||
factory.setStoreLocation("target/test-db");
|
||||
GraphDatabase graphDatabase = factory.getObject();
|
||||
|
||||
@@ -61,7 +61,7 @@ public class FullNeo4jTemplateTests {
|
||||
Neo4jTemplate neo4jTemplate;
|
||||
@Autowired
|
||||
protected GraphDatabase graphDatabase;
|
||||
protected Node referenceNode;
|
||||
protected Node node0;
|
||||
protected Relationship relationship1;
|
||||
protected Node node1;
|
||||
@Autowired
|
||||
@@ -78,15 +78,16 @@ public class FullNeo4jTemplateTests {
|
||||
Transaction tx = neo4jTemplate.getGraphDatabase().beginTx();
|
||||
try {
|
||||
Neo4jHelper.cleanDb(neo4jTemplate);
|
||||
tx.success();
|
||||
} finally {
|
||||
tx.success();tx.finish();
|
||||
tx.close();
|
||||
}
|
||||
tx = neo4jTemplate.getGraphDatabase().beginTx();
|
||||
try {
|
||||
referenceNode = graphDatabase.getReferenceNode();
|
||||
createData();
|
||||
tx.success();
|
||||
} finally {
|
||||
tx.success();tx.finish();
|
||||
tx.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,10 +96,10 @@ public class FullNeo4jTemplateTests {
|
||||
new TransactionTemplate(neo4jTransactionManager).execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
referenceNode.setProperty("name", "node0");
|
||||
graphDatabase.createIndex(Node.class, "node", IndexType.SIMPLE).add(referenceNode, "name", "node0");
|
||||
node0 = graphDatabase.createNode(map("name", "node0"));
|
||||
graphDatabase.createIndex(Node.class, "node", IndexType.SIMPLE).add(node0, "name", "node0");
|
||||
node1 = graphDatabase.createNode(map("name", "node1"));
|
||||
relationship1 = referenceNode.createRelationshipTo(node1, KNOWS);
|
||||
relationship1 = node0.createRelationshipTo(node1, KNOWS);
|
||||
relationship1.setProperty("name", "rel1");
|
||||
graphDatabase.createIndex(Relationship.class, "relationship", IndexType.SIMPLE).add(relationship1, "name", "rel1");
|
||||
}
|
||||
@@ -110,15 +111,15 @@ public class FullNeo4jTemplateTests {
|
||||
Node refNode = neo4jTemplate.exec(new GraphCallback<Node>() {
|
||||
@Override
|
||||
public Node doWithGraph(GraphDatabase graph) throws Exception {
|
||||
Node referenceNode = graph.getReferenceNode();
|
||||
Node referenceNode = graph.getNodeById(node0.getId());
|
||||
referenceNode.setProperty("test", "testDoInTransaction");
|
||||
return referenceNode;
|
||||
}
|
||||
});
|
||||
Transaction tx=graphDatabase.beginTx();
|
||||
try {
|
||||
assertEquals("same reference node", referenceNode, refNode);
|
||||
assertTestPropertySet(referenceNode, "testDoInTransaction");
|
||||
assertEquals("same reference node", node0, refNode);
|
||||
assertTestPropertySet(node0, "testDoInTransaction");
|
||||
} finally {
|
||||
tx.success();tx.finish();
|
||||
}
|
||||
@@ -130,7 +131,7 @@ public class FullNeo4jTemplateTests {
|
||||
neo4jTemplate.exec(new GraphCallback.WithoutResult() {
|
||||
@Override
|
||||
public void doWithGraphWithoutResult(GraphDatabase graph) throws Exception {
|
||||
graph.getReferenceNode().setProperty("test", "shouldRollbackTransactionOnException");
|
||||
graph.getNodeById(node0.getId()).setProperty("test", "shouldRollbackTransactionOnException");
|
||||
throw new RuntimeException("please rollback");
|
||||
}
|
||||
});
|
||||
@@ -139,7 +140,7 @@ public class FullNeo4jTemplateTests {
|
||||
}
|
||||
Transaction tx=graphDatabase.beginTx();
|
||||
try {
|
||||
Assert.assertThat((String) graphDatabase.getReferenceNode().getProperty("test", "not set"), not("shouldRollbackTransactionOnException"));
|
||||
Assert.assertThat((String) node0.getProperty("test", "not set"), not("shouldRollbackTransactionOnException"));
|
||||
} finally {
|
||||
tx.success();tx.finish();
|
||||
}
|
||||
@@ -153,7 +154,7 @@ public class FullNeo4jTemplateTests {
|
||||
neo4jTemplate.exec(new GraphCallback.WithoutResult() {
|
||||
@Override
|
||||
public void doWithGraphWithoutResult(GraphDatabase graph) throws Exception {
|
||||
graph.getReferenceNode().setProperty("test", "shouldRollbackTransactionOnException");
|
||||
node0.setProperty("test", "shouldRollbackTransactionOnException");
|
||||
status.setRollbackOnly();
|
||||
}
|
||||
});
|
||||
@@ -161,7 +162,7 @@ public class FullNeo4jTemplateTests {
|
||||
});
|
||||
Transaction tx=graphDatabase.beginTx();
|
||||
try {
|
||||
Assert.assertThat((String) graphDatabase.getReferenceNode().getProperty("test", "not set"), not("shouldRollbackTransactionOnException"));
|
||||
Assert.assertThat((String) node0.getProperty("test", "not set"), not("shouldRollbackTransactionOnException"));
|
||||
} finally {
|
||||
tx.success();tx.finish();
|
||||
}
|
||||
@@ -211,16 +212,10 @@ public class FullNeo4jTemplateTests {
|
||||
Long refNodeId = neo4jTemplate.exec(new GraphCallback<Long>() {
|
||||
@Override
|
||||
public Long doWithGraph(GraphDatabase graph) throws Exception {
|
||||
return graph.getReferenceNode().getId();
|
||||
return graph.getNodeById(node0.getId()).getId();
|
||||
}
|
||||
});
|
||||
assertEquals(referenceNode.getId(), (long) refNodeId);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void testGetReferenceNode() throws Exception {
|
||||
assertEquals(referenceNode, neo4jTemplate.getReferenceNode());
|
||||
assertEquals(node0.getId(), (long) refNodeId);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -260,8 +255,8 @@ public class FullNeo4jTemplateTests {
|
||||
@Test
|
||||
@Transactional
|
||||
public void testGetNode() throws Exception {
|
||||
Node lookedUpNode = neo4jTemplate.getNode(referenceNode.getId());
|
||||
assertEquals(referenceNode, lookedUpNode);
|
||||
Node lookedUpNode = neo4jTemplate.getNode(node0.getId());
|
||||
assertEquals(node0, lookedUpNode);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -319,31 +314,31 @@ public class FullNeo4jTemplateTests {
|
||||
public void testTraverse() throws Exception {
|
||||
//final TraversalDescription description = Traversal.description().relationships(KNOWS).prune(Traversal.pruneAfterDepth(1)).filter(Traversal.returnAllButStartNode());
|
||||
final TraversalDescription description = Traversal.description().relationships(KNOWS).evaluator(Evaluators.toDepth(1)).evaluator(Evaluators.excludeStartPosition());
|
||||
assertSingleResult("node1", neo4jTemplate.traverse(referenceNode, description).to(String.class, new PathNodeNameMapper()));
|
||||
assertSingleResult("node1", neo4jTemplate.traverse(node0, description).to(String.class, new PathNodeNameMapper()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void shouldFindNextNodeViaCypher() throws Exception {
|
||||
assertSingleResult(node1, neo4jTemplate.query("start n=node(0) match n-[:knows]->m return m", null).to(Node.class));
|
||||
assertSingleResult(node1, neo4jTemplate.query("start n=node(" + node0.getId() + ") match n-[:knows]->m return m", null).to(Node.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void shouldGetDirectRelationship() throws Exception {
|
||||
assertSingleResult("rel1", neo4jTemplate.convert(referenceNode.getRelationships(DynamicRelationshipType.withName("knows"))).to(String.class, new RelationshipNameConverter()));
|
||||
assertSingleResult("rel1", neo4jTemplate.convert(node0.getRelationships(DynamicRelationshipType.withName("knows"))).to(String.class, new RelationshipNameConverter()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void shouldGetDirectRelationshipForType() throws Exception {
|
||||
assertSingleResult("rel1", neo4jTemplate.convert(referenceNode.getRelationships(KNOWS)).to(String.class, new RelationshipNameConverter()));
|
||||
assertSingleResult("rel1", neo4jTemplate.convert(node0.getRelationships(KNOWS)).to(String.class, new RelationshipNameConverter()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void shouldGetDirectRelationshipForTypeAndDirection() throws Exception {
|
||||
assertSingleResult("rel1", neo4jTemplate.convert(referenceNode.getRelationships(KNOWS, Direction.OUTGOING)).to(String.class, new RelationshipNameConverter()));
|
||||
assertSingleResult("rel1", neo4jTemplate.convert(node0.getRelationships(KNOWS, Direction.OUTGOING)).to(String.class, new RelationshipNameConverter()));
|
||||
}
|
||||
|
||||
private <T> void assertSingleResult(T expected, Iterable<T> iterable) {
|
||||
@@ -356,9 +351,9 @@ public class FullNeo4jTemplateTests {
|
||||
@Test
|
||||
@Transactional
|
||||
public void shouldCreateRelationshipWithProperty() throws Exception {
|
||||
Relationship relationship = neo4jTemplate.createRelationshipBetween(referenceNode, node1, "has", map("name", "rel2"));
|
||||
Relationship relationship = neo4jTemplate.createRelationshipBetween(node0, node1, "has", map("name", "rel2"));
|
||||
assertNotNull(relationship);
|
||||
assertEquals(referenceNode, relationship.getStartNode());
|
||||
assertEquals(node0, relationship.getStartNode());
|
||||
assertEquals(node1, relationship.getEndNode());
|
||||
assertEquals(HAS.name(), relationship.getType().name());
|
||||
assertEquals("rel2", relationship.getProperty("name", "not set"));
|
||||
|
||||
@@ -30,13 +30,11 @@ import org.neo4j.test.TestGraphDatabaseFactory;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.neo4j.conversion.ResultConverter;
|
||||
import org.springframework.data.neo4j.core.GraphDatabase;
|
||||
import org.springframework.data.neo4j.model.Person;
|
||||
import org.springframework.data.neo4j.support.DelegatingGraphDatabase;
|
||||
import org.springframework.data.neo4j.support.Neo4jTemplate;
|
||||
import org.springframework.data.neo4j.support.index.IndexType;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.jta.JtaTransactionManager;
|
||||
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
@@ -56,7 +54,7 @@ public class Neo4jTemplateApiTests {
|
||||
private static final DynamicRelationshipType HAS = DynamicRelationshipType.withName("has");
|
||||
protected Neo4jTemplate template;
|
||||
protected GraphDatabase graphDatabase;
|
||||
protected Node referenceNode;
|
||||
protected Node node0;
|
||||
protected Relationship relationship1;
|
||||
protected Node node1;
|
||||
protected PlatformTransactionManager transactionManager;
|
||||
@@ -91,11 +89,10 @@ public class Neo4jTemplateApiTests {
|
||||
new TransactionTemplate(transactionManager).execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
referenceNode = graphDatabase.getReferenceNode();
|
||||
referenceNode.setProperty("name", "node0");
|
||||
graphDatabase.createIndex(Node.class, "node", IndexType.SIMPLE).add(referenceNode, "name", "node0");
|
||||
node0 = graphDatabase.createNode(map("name", "node0"));
|
||||
graphDatabase.createIndex(Node.class, "node", IndexType.SIMPLE).add(node0, "name", "node0");
|
||||
node1 = graphDatabase.createNode(map("name", "node1"));
|
||||
relationship1 = referenceNode.createRelationshipTo(node1, KNOWS);
|
||||
relationship1 = node0.createRelationshipTo(node1, KNOWS);
|
||||
relationship1.setProperty("name", "rel1");
|
||||
graphDatabase.createIndex(Relationship.class, "relationship", IndexType.SIMPLE).add(relationship1, "name", "rel1");
|
||||
}
|
||||
@@ -118,25 +115,16 @@ public class Neo4jTemplateApiTests {
|
||||
template.getNode(Long.MAX_VALUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetReferenceNode() throws Exception {
|
||||
assertEquals(referenceNode,template.getReferenceNode());
|
||||
}
|
||||
|
||||
private void assertTestPropertySet(Node node, String testName) {
|
||||
assertEquals(testName, node.getProperty("test","not set"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNode() throws Exception {
|
||||
Node lookedUpNode = template.getNode(referenceNode.getId());
|
||||
assertEquals(referenceNode,lookedUpNode);
|
||||
Node lookedUpNode = template.getNode(node0.getId());
|
||||
assertEquals(node0,lookedUpNode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRelationship() throws Exception {
|
||||
Relationship lookedUpRelationship = template.getRelationship(relationship1.getId());
|
||||
assertThat(lookedUpRelationship,is(relationship1));
|
||||
assertThat(lookedUpRelationship, is(relationship1));
|
||||
|
||||
}
|
||||
|
||||
@@ -152,7 +140,7 @@ public class Neo4jTemplateApiTests {
|
||||
template.index("node", node1, "name","node1");
|
||||
Index<Node> index = graphDatabase.getIndex("node");
|
||||
Node lookedUpNode= index.get( "name", "node1" ).getSingle();
|
||||
assertThat("same node from index",lookedUpNode,is(node1));
|
||||
assertThat("same node from index", lookedUpNode, is(node1));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -180,25 +168,25 @@ public class Neo4jTemplateApiTests {
|
||||
public void testTraverse() throws Exception {
|
||||
//final TraversalDescription description = Traversal.description().relationships(KNOWS).prune(Traversal.pruneAfterDepth(1)).filter(Traversal.returnAllButStartNode());
|
||||
final TraversalDescription description = Traversal.description().relationships(KNOWS).evaluator(Evaluators.toDepth(1)).evaluator(Evaluators.excludeStartPosition());
|
||||
assertSingleResult("node1",template.traverse(referenceNode, description).to(String.class,new PathNodeNameMapper()));
|
||||
assertSingleResult("node1",template.traverse(node0, description).to(String.class,new PathNodeNameMapper()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindNextNodeViaCypher() throws Exception {
|
||||
assertSingleResult(node1, template.query("start n=node(0) match n-->m return m", null).to(Node.class));
|
||||
assertSingleResult(node1, template.query("start n=node(" + node0.getId() + ") match n-->m return m", null).to(Node.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetDirectRelationship() throws Exception {
|
||||
assertSingleResult("rel1", template.convert(referenceNode.getRelationships()).to(String.class, new RelationshipNameConverter()));
|
||||
assertSingleResult("rel1", template.convert(node0.getRelationships()).to(String.class, new RelationshipNameConverter()));
|
||||
}
|
||||
@Test
|
||||
public void shouldGetDirectRelationshipForType() throws Exception {
|
||||
assertSingleResult("rel1", template.convert(referenceNode.getRelationships(KNOWS)).to(String.class, new RelationshipNameConverter()));
|
||||
assertSingleResult("rel1", template.convert(node0.getRelationships(KNOWS)).to(String.class, new RelationshipNameConverter()));
|
||||
}
|
||||
@Test
|
||||
public void shouldGetDirectRelationshipForTypeAndDirection() throws Exception {
|
||||
assertSingleResult("rel1", template.convert(referenceNode.getRelationships(KNOWS, Direction.OUTGOING)).to(String.class, new RelationshipNameConverter()));
|
||||
assertSingleResult("rel1", template.convert(node0.getRelationships(KNOWS, Direction.OUTGOING)).to(String.class, new RelationshipNameConverter()));
|
||||
}
|
||||
|
||||
private <T> void assertSingleResult(T expected, Iterable<T> iterable) {
|
||||
@@ -210,12 +198,12 @@ public class Neo4jTemplateApiTests {
|
||||
|
||||
@Test
|
||||
public void shouldCreateRelationshipWithProperty() throws Exception {
|
||||
Relationship relationship = template.createRelationshipBetween(referenceNode, node1, "has", map("name", "rel2"));
|
||||
Relationship relationship = template.createRelationshipBetween(node0, node1, "has", map("name", "rel2"));
|
||||
assertNotNull(relationship);
|
||||
assertEquals(referenceNode, relationship.getStartNode());
|
||||
assertEquals(node0, relationship.getStartNode());
|
||||
assertEquals(node1,relationship.getEndNode());
|
||||
assertEquals(HAS.name(), relationship.getType().name());
|
||||
assertEquals("rel2",relationship.getProperty("name","not set"));
|
||||
assertEquals("rel2",relationship.getProperty("name", "not set"));
|
||||
}
|
||||
|
||||
private static class PathNodeNameMapper extends ResultConverter.ResultConverterAdapter<Path,String> {
|
||||
|
||||
@@ -16,19 +16,12 @@
|
||||
|
||||
package org.springframework.data.neo4j.template;
|
||||
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.junit.*;
|
||||
import org.neo4j.graphdb.*;
|
||||
import org.neo4j.graphdb.index.Index;
|
||||
import org.neo4j.graphdb.traversal.Evaluators;
|
||||
import org.neo4j.graphdb.traversal.TraversalDescription;
|
||||
import org.neo4j.kernel.GraphDatabaseAPI;
|
||||
import org.neo4j.kernel.Traversal;
|
||||
import org.neo4j.kernel.impl.transaction.SpringTransactionManager;
|
||||
import org.neo4j.test.TestGraphDatabaseFactory;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.neo4j.conversion.ResultConverter;
|
||||
import org.springframework.data.neo4j.core.GraphDatabase;
|
||||
import org.springframework.data.neo4j.model.Person;
|
||||
import org.springframework.data.neo4j.support.DelegatingGraphDatabase;
|
||||
@@ -36,13 +29,11 @@ import org.springframework.data.neo4j.support.Neo4jTemplate;
|
||||
import org.springframework.data.neo4j.support.index.IndexType;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.jta.JtaTransactionManager;
|
||||
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.not;
|
||||
@@ -55,7 +46,7 @@ public class Neo4jTemplateApiTransactionTests {
|
||||
private static final DynamicRelationshipType HAS = DynamicRelationshipType.withName("has");
|
||||
protected Neo4jTemplate template;
|
||||
protected GraphDatabase graphDatabase;
|
||||
protected Node referenceNode;
|
||||
protected Node node0;
|
||||
protected Relationship relationship1;
|
||||
protected Node node1;
|
||||
protected PlatformTransactionManager transactionManager;
|
||||
@@ -87,13 +78,13 @@ public class Neo4jTemplateApiTransactionTests {
|
||||
Node node = template.createNode();
|
||||
node.setProperty("name","foo");
|
||||
tx.success();
|
||||
tx.finish();
|
||||
tx.close();
|
||||
|
||||
tx = template.getGraphDatabase().beginTx();
|
||||
try {
|
||||
assertNotNull(node.getProperty("name"));
|
||||
} finally {
|
||||
tx.success();tx.finish();
|
||||
tx.success();tx.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +96,7 @@ public class Neo4jTemplateApiTransactionTests {
|
||||
Person michael = template.save(new Person("Michael", 37));
|
||||
assertNotNull(michael.getId());
|
||||
} finally {
|
||||
tx.success();tx.finish();
|
||||
tx.success();tx.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,11 +108,10 @@ public class Neo4jTemplateApiTransactionTests {
|
||||
new TransactionTemplate(transactionManager).execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
referenceNode = graphDatabase.getReferenceNode();
|
||||
referenceNode.setProperty("name", "node0");
|
||||
graphDatabase.createIndex(Node.class, "node", IndexType.SIMPLE).add(referenceNode, "name", "node0");
|
||||
node0 = graphDatabase.createNode(map("name", "node0"));
|
||||
graphDatabase.createIndex(Node.class, "node", IndexType.SIMPLE).add(node0, "name", "node0");
|
||||
node1 = graphDatabase.createNode(map("name", "node1"));
|
||||
relationship1 = referenceNode.createRelationshipTo(node1, KNOWS);
|
||||
relationship1 = node0.createRelationshipTo(node1, KNOWS);
|
||||
relationship1.setProperty("name", "rel1");
|
||||
graphDatabase.createIndex(Relationship.class, "relationship", IndexType.SIMPLE).add(relationship1, "name", "rel1");
|
||||
}
|
||||
@@ -133,17 +123,17 @@ public class Neo4jTemplateApiTransactionTests {
|
||||
Node refNode = template.exec(new GraphCallback<Node>() {
|
||||
@Override
|
||||
public Node doWithGraph(GraphDatabase graph) throws Exception {
|
||||
Node referenceNode = graph.getReferenceNode();
|
||||
Node referenceNode = graph.getNodeById(node0.getId());
|
||||
referenceNode.setProperty("test", "testDoInTransaction");
|
||||
return referenceNode;
|
||||
}
|
||||
});
|
||||
Transaction tx = graphDatabase.beginTx();
|
||||
try {
|
||||
assertEquals("same reference node", referenceNode, refNode);
|
||||
assertTestPropertySet(referenceNode, "testDoInTransaction");
|
||||
assertEquals("same reference node", node0, refNode);
|
||||
assertTestPropertySet(node0, "testDoInTransaction");
|
||||
} finally {
|
||||
tx.success();tx.finish();
|
||||
tx.success();tx.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +143,7 @@ public class Neo4jTemplateApiTransactionTests {
|
||||
template.exec(new GraphCallback.WithoutResult() {
|
||||
@Override
|
||||
public void doWithGraphWithoutResult(GraphDatabase graph) throws Exception {
|
||||
graph.getReferenceNode().setProperty("test", "shouldRollbackTransactionOnException");
|
||||
node0.setProperty("test", "shouldRollbackTransactionOnException");
|
||||
throw new RuntimeException("please rollback");
|
||||
}
|
||||
});
|
||||
@@ -162,9 +152,9 @@ public class Neo4jTemplateApiTransactionTests {
|
||||
}
|
||||
Transaction tx = graphDatabase.beginTx();
|
||||
try {
|
||||
Assert.assertThat((String) graphDatabase.getReferenceNode().getProperty("test", "not set"), not("shouldRollbackTransactionOnException"));
|
||||
Assert.assertThat((String) node0.getProperty("test", "not set"), not("shouldRollbackTransactionOnException"));
|
||||
} finally {
|
||||
tx.success();tx.finish();
|
||||
tx.success();tx.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,7 +166,7 @@ public class Neo4jTemplateApiTransactionTests {
|
||||
template.exec(new GraphCallback.WithoutResult() {
|
||||
@Override
|
||||
public void doWithGraphWithoutResult(GraphDatabase graph) throws Exception {
|
||||
graph.getReferenceNode().setProperty("test", "shouldRollbackTransactionOnException");
|
||||
node0.setProperty("test", "shouldRollbackTransactionOnException");
|
||||
status.setRollbackOnly();
|
||||
}
|
||||
});
|
||||
@@ -184,9 +174,9 @@ public class Neo4jTemplateApiTransactionTests {
|
||||
});
|
||||
Transaction tx = graphDatabase.beginTx();
|
||||
try {
|
||||
Assert.assertThat((String) graphDatabase.getReferenceNode().getProperty("test", "not set"), not("shouldRollbackTransactionOnException"));
|
||||
Assert.assertThat((String) node0.getProperty("test", "not set"), not("shouldRollbackTransactionOnException"));
|
||||
} finally {
|
||||
tx.success();tx.finish();
|
||||
tx.success();tx.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,14 +217,14 @@ public class Neo4jTemplateApiTransactionTests {
|
||||
Long refNodeId = template.exec(new GraphCallback<Long>() {
|
||||
@Override
|
||||
public Long doWithGraph(GraphDatabase graph) throws Exception {
|
||||
return graph.getReferenceNode().getId();
|
||||
return graph.getNodeById(node0.getId()).getId();
|
||||
}
|
||||
});
|
||||
Transaction tx = graphDatabase.beginTx();
|
||||
try {
|
||||
assertEquals(referenceNode.getId(), (long) refNodeId);
|
||||
assertEquals(node0.getId(), (long) refNodeId);
|
||||
} finally {
|
||||
tx.success();tx.finish();
|
||||
tx.success();tx.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package org.springframework.data.neo4j.template;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.neo4j.graphdb.*;
|
||||
import org.springframework.data.neo4j.core.GraphDatabase;
|
||||
@@ -30,6 +30,8 @@ import static org.springframework.data.neo4j.template.Neo4jTemplateTests.Type.HA
|
||||
|
||||
public class Neo4jTemplateTests extends NeoApiTests {
|
||||
|
||||
private Node refNode;
|
||||
|
||||
enum Type implements RelationshipType {
|
||||
HAS
|
||||
}
|
||||
@@ -38,13 +40,12 @@ public class Neo4jTemplateTests extends NeoApiTests {
|
||||
public void testRefNode() {
|
||||
Node refNodeById = new Neo4jTemplate(graph, transactionManager).exec(new GraphCallback<Node>() {
|
||||
public Node doWithGraph(GraphDatabase graph) throws Exception {
|
||||
Node refNode = graph.getReferenceNode();
|
||||
return graph.getNodeById( refNode.getId() );
|
||||
}
|
||||
});
|
||||
|
||||
try (Transaction tx=graph.beginTx()) {
|
||||
assertEquals("same ref node", graph.getReferenceNode(), refNodeById);
|
||||
assertEquals("same ref node", refNode, refNodeById);
|
||||
tx.success();
|
||||
}
|
||||
}
|
||||
@@ -55,7 +56,6 @@ public class Neo4jTemplateTests extends NeoApiTests {
|
||||
template.exec(new GraphCallback.WithoutResult() {
|
||||
@Override
|
||||
public void doWithGraphWithoutResult(GraphDatabase graph) throws Exception {
|
||||
Node refNode = graph.getReferenceNode();
|
||||
Node node = graph.createNode(map("name", "Test", "size", 100));
|
||||
refNode.createRelationshipTo(node, HAS);
|
||||
|
||||
@@ -67,7 +67,6 @@ public class Neo4jTemplateTests extends NeoApiTests {
|
||||
});
|
||||
template.exec(new GraphCallback.WithoutResult() {
|
||||
public void doWithGraphWithoutResult(GraphDatabase graph) throws Exception {
|
||||
Node refNode = graph.getReferenceNode();
|
||||
final Relationship toTestNode = refNode.getSingleRelationship(HAS, Direction.OUTGOING);
|
||||
final Node nodeByRelationship = toTestNode.getEndNode();
|
||||
assertEquals("Test", nodeByRelationship.getProperty("name"));
|
||||
@@ -83,7 +82,7 @@ public class Neo4jTemplateTests extends NeoApiTests {
|
||||
template.exec(new GraphCallback.WithoutResult() {
|
||||
@Override
|
||||
public void doWithGraphWithoutResult(GraphDatabase graph) throws Exception {
|
||||
Node node = graph.getReferenceNode();
|
||||
Node node = refNode;
|
||||
node.setProperty("test", "test");
|
||||
assertEquals("test", node.getProperty("test"));
|
||||
throw new RuntimeException();
|
||||
@@ -92,9 +91,20 @@ public class Neo4jTemplateTests extends NeoApiTests {
|
||||
} catch(RuntimeException ignore) {}
|
||||
template.exec(new GraphCallback.WithoutResult() {
|
||||
public void doWithGraphWithoutResult(final GraphDatabase graph) throws Exception {
|
||||
Node node = graph.getReferenceNode();
|
||||
assertFalse(node.hasProperty("test"));
|
||||
assertFalse(refNode.hasProperty("test"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
refNode = new Neo4jTemplate(graph, transactionManager).exec(new GraphCallback<Node>() {
|
||||
public Node doWithGraph(GraphDatabase graph) throws Exception {
|
||||
return graph.createNode(map());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,12 +26,14 @@ import org.neo4j.kernel.Traversal;
|
||||
import org.springframework.data.neo4j.conversion.Handler;
|
||||
import org.springframework.data.neo4j.conversion.Result;
|
||||
import org.springframework.data.neo4j.core.GraphDatabase;
|
||||
import org.springframework.data.neo4j.support.ReferenceNodes;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.neo4j.helpers.collection.MapUtil.map;
|
||||
// TODO import static org.neo4j.kernel.Traversal.returnAllButStartNode;
|
||||
import static org.springframework.data.neo4j.template.NeoTraversalTests.Type.HAS;
|
||||
@@ -44,10 +46,10 @@ public class NeoTraversalTests extends NeoApiTests {
|
||||
|
||||
@Test
|
||||
public void testSimpleTraverse() {
|
||||
template.exec(new GraphCallback.WithoutResult() {
|
||||
final Node family = template.exec(new GraphCallback<Node>() {
|
||||
@Override
|
||||
public void doWithGraphWithoutResult(GraphDatabase graph) throws Exception {
|
||||
createFamily();
|
||||
public Node doWithGraph(GraphDatabase graph) throws Exception {
|
||||
return createFamily();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -55,10 +57,9 @@ public class NeoTraversalTests extends NeoApiTests {
|
||||
@Override
|
||||
public void doWithGraphWithoutResult(GraphDatabase graph) throws Exception {
|
||||
final Set<String> resultSet = new HashSet<String>();
|
||||
// @SuppressWarnings("deprecation") final TraversalDescription description = Traversal.description().relationships(HAS).filter(returnAllButStartNode()).prune(Traversal.pruneAfterDepth(2));
|
||||
final TraversalDescription description = Traversal.description().relationships(HAS).evaluator(Evaluators.excludeStartPosition()).evaluator(Evaluators.toDepth(2));
|
||||
final TraversalDescription description = Traversal.description().relationships(HAS).evaluator(Evaluators.excludeStartPosition()).evaluator(Evaluators.toDepth(1));
|
||||
|
||||
final Result<Path> result = template.traverse(template.getReferenceNode(), description);
|
||||
final Result<Path> result = template.traverse(family, description);
|
||||
result.handle(new Handler<Path>() {
|
||||
@Override
|
||||
public void handle(Path value) {
|
||||
@@ -66,13 +67,13 @@ public class NeoTraversalTests extends NeoApiTests {
|
||||
resultSet.add(name);
|
||||
}
|
||||
});
|
||||
assertEquals("all members", new HashSet<String>(asList("grandpa", "grandma", "daughter", "son", "man", "wife", "family")), resultSet);
|
||||
assertEquals("all members", new HashSet<String>(asList("grandpa", "grandma", "daughter", "son", "man", "wife")), resultSet);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void createFamily() {
|
||||
private Node createFamily() {
|
||||
|
||||
Node family = template.createNode(map("name", "family"));
|
||||
Node man = template.createNode(map("name", "wife"));
|
||||
@@ -103,6 +104,6 @@ public class NeoTraversalTests extends NeoApiTests {
|
||||
grandma.createRelationshipTo(daughter, Type.GRANDDAUGHTER);
|
||||
grandpa.createRelationshipTo(daughter, Type.GRANDDAUGHTER);
|
||||
|
||||
graph.getReferenceNode().createRelationshipTo(family,HAS);
|
||||
return family;
|
||||
}
|
||||
}
|
||||
@@ -22,12 +22,14 @@ import org.neo4j.test.TestGraphDatabaseFactory;
|
||||
import org.springframework.data.neo4j.model.Person;
|
||||
import org.springframework.data.neo4j.support.MappingInfrastructureFactoryBean;
|
||||
import org.springframework.data.neo4j.support.Neo4jTemplate;
|
||||
import org.springframework.data.neo4j.support.ReferenceNodes;
|
||||
import org.springframework.data.neo4j.support.typerepresentation.TypeRepresentationStrategyFactory;
|
||||
|
||||
public class TypeRepresentationTests {
|
||||
@Test
|
||||
public void testSavingTwiceResultsOnlyInOneTRSCall() throws Exception {
|
||||
GraphDatabaseService db = new TestGraphDatabaseFactory().newImpermanentDatabase();
|
||||
ReferenceNodes.obtainReferenceNode(db,"root");
|
||||
MappingInfrastructureFactoryBean factoryBean = new MappingInfrastructureFactoryBean(db, null);
|
||||
factoryBean.setTypeRepresentationStrategy(TypeRepresentationStrategyFactory.Strategy.SubRef);
|
||||
factoryBean.afterPropertiesSet();
|
||||
@@ -37,6 +39,6 @@ public class TypeRepresentationTests {
|
||||
person.setName("Bar");
|
||||
template.save(person);
|
||||
tx.failure();
|
||||
tx.finish();
|
||||
tx.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<context:annotation-config />
|
||||
|
||||
|
||||
<bean name="graphDatabase" class="org.springframework.data.neo4j.support.GraphDatabaseFactory">
|
||||
<bean name="graphDatabase" class="org.springframework.data.neo4j.support.GraphDatabaseFactoryBean">
|
||||
<property name="storeLocation" value="target/test-db"/>
|
||||
|
||||
</bean>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
<bean class="org.springframework.context.annotation.ConfigurationClassPostProcessor"/>
|
||||
|
||||
<bean id="graphDatabaseService" class="org.neo4j.kernel.EmbeddedGraphDatabase" destroy-method="shutdown">
|
||||
<bean id="graphDatabaseService" class="org.springframework.data.neo4j.support.GraphDatabaseServiceFactoryBean" destroy-method="shutdown">
|
||||
<constructor-arg index="0" value="target/config-test"/>
|
||||
</bean>
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
<context:annotation-config/>
|
||||
|
||||
<bean id="graphDatabaseService" class="org.neo4j.kernel.EmbeddedGraphDatabase"
|
||||
<bean id="graphDatabaseService" class="org.springframework.data.neo4j.support.GraphDatabaseServiceFactoryBean"
|
||||
destroy-method="shutdown" scope="singleton">
|
||||
<constructor-arg value="target/config-test"/>
|
||||
<constructor-arg>
|
||||
|
||||
@@ -94,7 +94,7 @@ try {
|
||||
relationship.setProperty( "message", "brave Neo4j" );
|
||||
tx.success();
|
||||
} finally {
|
||||
tx.finish();
|
||||
tx.close();
|
||||
}
|
||||
]]></programlisting>
|
||||
</example>
|
||||
@@ -145,7 +145,7 @@ try {
|
||||
nodeIndex.add(node, "property","value");
|
||||
tx.success();
|
||||
} finally {
|
||||
tx.finish();
|
||||
tx.close();
|
||||
}
|
||||
for (Node foundNode : nodeIndex.get("property","value")) {
|
||||
// found node
|
||||
|
||||
Reference in New Issue
Block a user