public void importFromFile(String filePath) throws IOException { Map<String, Long> cache = new HashMap<String, Long>(COUNT); final File storeDir = new File(this.path); org.apache.commons.io.FileUtils.deleteDirectory(storeDir); BatchInserter batchInserter = new BatchInserterImpl(storeDir.getAbsolutePath()); final BatchInserterIndexProvider indexProvider = new LuceneBatchInserterIndexProvider(batchInserter); final BatchInserterIndex index = indexProvider.nodeIndex("nodes", MapUtil.stringMap("type", "exact")); BufferedReader reader = new BufferedReader(new FileReader(filePath)); String line = null; int nodes = 0; long time = System.currentTimeMillis(); long batchTime = time; while ((line = reader.readLine()) != null) { final String[] nodeNames = line.split("\\|"); final String name = nodeNames[0]; final Map<String, Object> props = MapUtil.map("name", name); final long node = batchInserter.createNode(props); index.add(node, props); cache.put(name, node); nodes++; if ((nodes % REPORT_COUNT) == 0) { System.out.printf( "%d nodes created. Took %d %n", nodes, (System.currentTimeMillis() - batchTime)); batchTime = System.currentTimeMillis(); } } System.out.println("Creating nodes took " + (System.currentTimeMillis() - time) / 1000); index.flush(); reader.close(); reader = new BufferedReader(new FileReader(filePath)); int rels = 0; time = System.currentTimeMillis(); batchTime = time; String relationshipType = "KNOWS"; while ((line = reader.readLine()) != null) { final String[] nodeNames = line.split("\\|"); final String name = nodeNames[0]; // final Long from = index.get("name", name).getSingle(); Long from = cache.get(name); for (int j = 1; j < nodeNames.length; j++) { // final Long to = index.get("name", nodeNames[j]).getSingle(); final Long to = cache.get(name); batchInserter.createRelationship( from, to, DynamicRelationshipType.withName(relationshipType), null); } rels++; if ((rels % REPORT_COUNT) == 0) { System.out.printf( "%d relationships created. Took %d %n", rels, (System.currentTimeMillis() - batchTime)); batchTime = System.currentTimeMillis(); } } System.out.println("Creating relationships took " + (System.currentTimeMillis() - time) / 1000); indexProvider.shutdown(); batchInserter.shutdown(); }
protected List<Node> getRelatedNodes(Node startNode, String type, Direction direction) { List<Node> result = new ArrayList<Node>(); for (Relationship relationship : startNode.getRelationships(DynamicRelationshipType.withName(type), direction)) { result.add(relationship.getOtherNode(startNode)); } return result; }
@Test @Transactional public void shouldGetDirectRelationship() throws Exception { assertSingleResult( "rel1", neo4jTemplate .convert(referenceNode.getRelationships(DynamicRelationshipType.withName("knows"))) .to(String.class, new RelationshipNameConverter())); }
@Test @Transactional public void shouldCreateRelationshipWithProperty() throws Exception { Relationship relationship = neo4jTemplate.createRelationshipBetween(referenceNode, node1, "has", map("name", "rel2")); assertNotNull(relationship); assertEquals(referenceNode, relationship.getStartNode()); assertEquals(node1, relationship.getEndNode()); assertEquals(HAS.name(), relationship.getType().name()); assertEquals("rel2", relationship.getProperty("name", "not set")); }
@Test public void testCreateRelationshipToNodeOutsideofBatch() throws Exception { final Node node1 = restAPI.createNode(map()); final Transaction tx = restAPI.beginTx(); Node node2 = restAPI.createNode(map()); final Relationship relationship = node1.createRelationshipTo(node2, DynamicRelationshipType.withName("foo")); tx.success(); tx.finish(); assertEquals("foo", relationship.getType().name()); assertEquals( "foo", getGraphDatabase().getRelationshipById(relationship.getId()).getType().name()); }
@Test public void deletedRelationshipWithNewTypeShouldNotInfluenceEquality() { // bug test try (Transaction tx = database.beginTx()) { Node node1 = database.createNode(); Node node2 = database.createNode(); node1.createRelationshipTo(node2, DynamicRelationshipType.withName("ACCIDENT")); tx.success(); } try (Transaction tx = database.beginTx()) { GlobalGraphOperations.at(database).getAllRelationships().iterator().next().delete(); tx.success(); } String cypher = "CREATE (n), (m)"; assertSameGraph(database, cypher); }
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:template-config-context.xml"}) public class FullNeo4jTemplateTests { private static final DynamicRelationshipType KNOWS = DynamicRelationshipType.withName("knows"); private static final DynamicRelationshipType HAS = DynamicRelationshipType.withName("has"); @Autowired Neo4jTemplate neo4jTemplate; @Autowired protected GraphDatabase graphDatabase; protected Node referenceNode; protected Relationship relationship1; protected Node node1; @Autowired PlatformTransactionManager neo4jTransactionManager; @BeforeTransaction public void cleanDb() { Neo4jHelper.cleanDb(neo4jTemplate); } @Before public void setUp() throws Exception { Transaction tx = neo4jTemplate.getGraphDatabase().beginTx(); try { Neo4jHelper.cleanDb(neo4jTemplate); } finally { tx.success(); tx.finish(); } tx = neo4jTemplate.getGraphDatabase().beginTx(); try { referenceNode = graphDatabase.getReferenceNode(); createData(); } finally { tx.success(); tx.finish(); } } private void createData() { 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"); node1 = graphDatabase.createNode(map("name", "node1")); relationship1 = referenceNode.createRelationshipTo(node1, KNOWS); relationship1.setProperty("name", "rel1"); graphDatabase .createIndex(Relationship.class, "relationship", IndexType.SIMPLE) .add(relationship1, "name", "rel1"); } }); } @Test public void shouldExecuteCallbackInTransaction() throws Exception { Node refNode = neo4jTemplate.exec( new GraphCallback<Node>() { @Override public Node doWithGraph(GraphDatabase graph) throws Exception { Node referenceNode = graph.getReferenceNode(); referenceNode.setProperty("test", "testDoInTransaction"); return referenceNode; } }); Transaction tx = graphDatabase.beginTx(); try { assertEquals("same reference node", referenceNode, refNode); assertTestPropertySet(referenceNode, "testDoInTransaction"); } finally { tx.success(); tx.finish(); } } @Test public void shouldRollbackTransactionOnException() { try { neo4jTemplate.exec( new GraphCallback.WithoutResult() { @Override public void doWithGraphWithoutResult(GraphDatabase graph) throws Exception { graph.getReferenceNode().setProperty("test", "shouldRollbackTransactionOnException"); throw new RuntimeException("please rollback"); } }); } catch (RuntimeException re) { } Transaction tx = graphDatabase.beginTx(); try { Assert.assertThat( (String) graphDatabase.getReferenceNode().getProperty("test", "not set"), not("shouldRollbackTransactionOnException")); } finally { tx.success(); tx.finish(); } } @Test public void shouldRollbackViaStatus() throws Exception { new TransactionTemplate(neo4jTransactionManager) .execute( new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(final TransactionStatus status) { neo4jTemplate.exec( new GraphCallback.WithoutResult() { @Override public void doWithGraphWithoutResult(GraphDatabase graph) throws Exception { graph .getReferenceNode() .setProperty("test", "shouldRollbackTransactionOnException"); status.setRollbackOnly(); } }); } }); Transaction tx = graphDatabase.beginTx(); try { Assert.assertThat( (String) graphDatabase.getReferenceNode().getProperty("test", "not set"), not("shouldRollbackTransactionOnException")); } finally { tx.success(); tx.finish(); } } @Test(expected = RuntimeException.class) public void shouldNotConvertUserRuntimeExceptionToDataAccessException() { neo4jTemplate.exec( new GraphCallback.WithoutResult() { @Override public void doWithGraphWithoutResult(GraphDatabase graph) throws Exception { throw new RuntimeException(); } }); } @Test(expected = DataAccessException.class) @Ignore public void shouldConvertMissingTransactionExceptionToDataAccessException() { Neo4jTemplate template = new Neo4jTemplate(graphDatabase, null); template.exec( new GraphCallback.WithoutResult() { @Override public void doWithGraphWithoutResult(GraphDatabase graph) throws Exception { graph.createNode(null); } }); } @Test(expected = DataAccessException.class) public void shouldConvertNotFoundExceptionToDataAccessException() { Neo4jTemplate template = new Neo4jTemplate(graphDatabase, neo4jTransactionManager); template.exec( new GraphCallback.WithoutResult() { @Override public void doWithGraphWithoutResult(GraphDatabase graph) throws Exception { graph.getNodeById(Long.MAX_VALUE); } }); } @Test(expected = DataAccessException.class) public void shouldConvertTemplateNotFoundExceptionToDataAccessException() { neo4jTemplate.getNode(Long.MAX_VALUE); } @Test @Transactional public void shouldExecuteCallback() throws Exception { Long refNodeId = neo4jTemplate.exec( new GraphCallback<Long>() { @Override public Long doWithGraph(GraphDatabase graph) throws Exception { return graph.getReferenceNode().getId(); } }); assertEquals(referenceNode.getId(), (long) refNodeId); } @Test @Transactional public void testGetReferenceNode() throws Exception { assertEquals(referenceNode, neo4jTemplate.getReferenceNode()); } @Test @Transactional public void testCreateNode() throws Exception { Node node = neo4jTemplate.createNode(null); assertNotNull("created node", node); } @Test @Transactional public void testCreateEntityWithProperties() throws Exception { Person person = neo4jTemplate.createNodeAs(Person.class, map("name", "name")); assertNotNull("created node", person); assertEquals("property created", "name", person.getName()); } @Test @Transactional public void testCreateNodeTypeWithProperties() throws Exception { Node person = neo4jTemplate.createNodeAs(Node.class, map("name", "name")); assertNotNull("created node", person); assertEquals("property created", "name", person.getProperty("name")); } @Test @Transactional public void testCreateNodeWithProperties() throws Exception { Node node = neo4jTemplate.createNode(map("test", "testCreateNodeWithProperties")); assertTestPropertySet(node, "testCreateNodeWithProperties"); } private void assertTestPropertySet(Node node, String testName) { assertEquals(testName, node.getProperty("test", "not set")); } @Test @Transactional public void testGetNode() throws Exception { Node lookedUpNode = neo4jTemplate.getNode(referenceNode.getId()); assertEquals(referenceNode, lookedUpNode); } @Test @Transactional public void testGetRelationship() throws Exception { Relationship lookedUpRelationship = neo4jTemplate.getRelationship(relationship1.getId()); assertThat(lookedUpRelationship, is(relationship1)); } @Test @Transactional public void testIndexRelationship() throws Exception { Index<Relationship> index = graphDatabase.getIndex("relationship"); Relationship lookedUpRelationship = index.get("name", "rel1").getSingle(); assertThat("same relationship from index", lookedUpRelationship, is(relationship1)); } @Test @Transactional public void testIndexNode() throws Exception { neo4jTemplate.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)); } @Test @Transactional public void testQueryNodes() throws Exception { assertSingleResult( "node0", neo4jTemplate .lookup("node", new TermQuery(new Term("name", "node0"))) .to(String.class, new PropertyContainerNameConverter())); } @Test @Transactional public void testRetrieveNodes() throws Exception { assertSingleResult( "node0", neo4jTemplate .lookup("node", "name", "node0") .to(String.class, new PropertyContainerNameConverter())); } @Test @Transactional public void testQueryRelationships() throws Exception { assertSingleResult( "rel1", neo4jTemplate .lookup("relationship", new TermQuery(new Term("name", "rel1"))) .to(String.class, new PropertyContainerNameConverter())); } @Test @Transactional public void testRetrieveRelationships() throws Exception { assertSingleResult( "rel1", neo4jTemplate .lookup("relationship", "name", "rel1") .to(String.class, new PropertyContainerNameConverter())); } @SuppressWarnings("deprecation") @Test @Transactional 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())); } @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)); } @Test @Transactional public void shouldGetDirectRelationship() throws Exception { assertSingleResult( "rel1", neo4jTemplate .convert(referenceNode.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())); } @Test @Transactional public void shouldGetDirectRelationshipForTypeAndDirection() throws Exception { assertSingleResult( "rel1", neo4jTemplate .convert(referenceNode.getRelationships(KNOWS, Direction.OUTGOING)) .to(String.class, new RelationshipNameConverter())); } private <T> void assertSingleResult(T expected, Iterable<T> iterable) { Iterator<T> result = iterable.iterator(); assertEquals(expected, result.next()); assertEquals(false, result.hasNext()); } @Test @Transactional public void shouldCreateRelationshipWithProperty() throws Exception { Relationship relationship = neo4jTemplate.createRelationshipBetween(referenceNode, node1, "has", map("name", "rel2")); assertNotNull(relationship); assertEquals(referenceNode, relationship.getStartNode()); assertEquals(node1, relationship.getEndNode()); assertEquals(HAS.name(), relationship.getType().name()); assertEquals("rel2", relationship.getProperty("name", "not set")); } private static class PathRelationshipNameMapper extends ResultConverter.ResultConverterAdapter<Path, String> { @Override public String convert(Path path, Class<String> type) { return (String) path.lastRelationship().getProperty("name", "not set"); } } private static class PathNodeNameMapper extends ResultConverter.ResultConverterAdapter<Path, String> { @Override public String convert(Path path, Class<String> type) { return (String) path.endNode().getProperty("name", "not set"); } } private static class RelationshipNameConverter extends ResultConverter.ResultConverterAdapter<Relationship, String> { @Override public String convert(Relationship value, Class<String> type) { return (String) value.getProperty("name"); } } private static class PropertyContainerNameConverter extends ResultConverter.ResultConverterAdapter<PropertyContainer, String> { @Override public String convert(PropertyContainer value, Class<String> type) { return (String) value.getProperty("name"); } } }
/** * @author mh * @since 12.10.11 */ public class Neo4jPersistentTestBase { private Transaction tx; protected Neo4jTemplate template; protected NodeEntityStateFactory nodeEntityStateFactory; protected RelationshipEntityStateFactory relationshipEntityStateFactory; protected EntityStateHandler entityStateHandler; protected NodeEntityInstantiator nodeEntityInstantiator; protected RelationshipEntityInstantiator relationshipEntityInstantiator; protected TypeMapper<Node> nodeTypeMapper; protected SourceStateTransmitter<Node> nodeStateTransmitter; protected SourceStateTransmitter<Relationship> relationshipStateTransmitter; protected ConversionService conversionService; protected Neo4jEntityFetchHandler fetchHandler; protected Neo4jMappingContext mappingContext; protected Neo4jEntityPersister entityPersister; protected Group group; protected Person michael; protected Person emil; protected Person andres; public static final RelationshipType PERSONS = DynamicRelationshipType.withName("persons"); protected static final RelationshipType KNOWS = DynamicRelationshipType.withName("knows"); @NodeEntity public static class Developer { @GraphId Long id; String name; } @Before public void setUp() throws Exception { // todo cleanup !! mappingContext = new Neo4jMappingContext(); MappingInfrastructure infrastructure = createInfrastructure(mappingContext); template = new Neo4jTemplate(infrastructure); nodeEntityStateFactory = createNodeEntityStateFactory(mappingContext); relationshipEntityStateFactory = createRelationshipEntityStateFactory(mappingContext); infrastructure.setNodeEntityStateFactory(nodeEntityStateFactory); infrastructure.setRelationshipEntityStateFactory(relationshipEntityStateFactory); template.postConstruct(); entityStateHandler = infrastructure.getEntityStateHandler(); nodeEntityInstantiator = new NodeEntityInstantiator(entityStateHandler); relationshipEntityInstantiator = new RelationshipEntityInstantiator(entityStateHandler); nodeTypeMapper = new DefaultTypeMapper<Node>( new TRSTypeAliasAccessor<Node>(infrastructure.getNodeTypeRepresentationStrategy()), asList(new ClassValueTypeInformationMapper())); nodeStateTransmitter = new SourceStateTransmitter<Node>(nodeEntityStateFactory); relationshipStateTransmitter = new SourceStateTransmitter<Relationship>(relationshipEntityStateFactory); conversionService = template.getConversionService(); fetchHandler = new Neo4jEntityFetchHandler( entityStateHandler, conversionService, nodeStateTransmitter, relationshipStateTransmitter); final EntityTools<Node> nodeEntityTools = new EntityTools<Node>( infrastructure.getNodeTypeRepresentationStrategy(), nodeEntityStateFactory, nodeEntityInstantiator); final EntityTools<Relationship> relationshipEntityTools = new EntityTools<Relationship>( infrastructure.getRelationshipTypeRepresentationStrategy(), relationshipEntityStateFactory, relationshipEntityInstantiator); entityPersister = new Neo4jEntityPersister( conversionService, nodeEntityTools, relationshipEntityTools, mappingContext, entityStateHandler); tx = template.beginTx(); group = new Group(); michael = new Person("Michael", 37); emil = new Person("Emil", 30); andres = new Person("Andrés", 36); } private NodeEntityStateFactory createNodeEntityStateFactory(Neo4jMappingContext mappingContext) { final NodeEntityStateFactory nodeEntityStateFactory = new NodeEntityStateFactory(); nodeEntityStateFactory.setMappingContext(mappingContext); nodeEntityStateFactory.setTemplate(template); nodeEntityStateFactory.setNodeDelegatingFieldAccessorFactory( new NodeDelegatingFieldAccessorFactory(template)); return nodeEntityStateFactory; } private RelationshipEntityStateFactory createRelationshipEntityStateFactory( Neo4jMappingContext mappingContext) { final RelationshipEntityStateFactory relationshipEntityStateFactory = new RelationshipEntityStateFactory(); relationshipEntityStateFactory.setMappingContext(mappingContext); relationshipEntityStateFactory.setTemplate(template); relationshipEntityStateFactory.setRelationshipDelegatingFieldAccessorFactory( new RelationshipDelegatingFieldAccessorFactory(template)); return relationshipEntityStateFactory; } private MappingInfrastructure createInfrastructure(Neo4jMappingContext mappingContext) throws Exception { MappingInfrastructure infrastructure = new MappingInfrastructure(); final GraphDatabaseService gdb = new ImpermanentGraphDatabase(); infrastructure.setGraphDatabaseService(gdb); final DelegatingGraphDatabase graphDatabase = new DelegatingGraphDatabase(gdb); infrastructure.setGraphDatabase(graphDatabase); infrastructure.setMappingContext(mappingContext); final EntityStateHandler entityStateHandler = new EntityStateHandler(mappingContext, graphDatabase); infrastructure.setNodeTypeRepresentationStrategy(new NoopNodeTypeRepresentationStrategy()); infrastructure.setRelationshipTypeRepresentationStrategy( new NoopRelationshipTypeRepresentationStrategy()); infrastructure.setConversionService(new Neo4jConversionServiceFactoryBean().getObject()); infrastructure.setEntityStateHandler(entityStateHandler); return infrastructure; } protected List<Node> groupMemberNodes() { return groupMemberNodes(groupNode()); } private List<Node> groupMemberNodes(Node node) { return getRelatedNodes(node, "persons", Direction.OUTGOING); } @After public void tearDown() throws Exception { tx.failure(); tx.finish(); template.getGraphDatabaseService().shutdown(); } protected Node michaelNode() { return template.getNode(michael.getId()); } protected Node createNewNode() { return template.createNode(); } protected Group storeInGraph(Group g) { final Long id = g.getId(); if (id != null) { write(g, template.getNode(id)); } else { write(g, null); } return g; } protected Person storeInGraph(Person p) { final Long id = p.getId(); if (id != null) { write(p, template.getNode(id)); } else { write(p, null); } return p; } protected Object write(Object entity, Node node) { entityPersister.write(entity, node); return entity; } @SuppressWarnings("unchecked") private <T> T storeInGraph(T obj) { return (T) write(obj, null); } protected Node groupNode() { return template.getNode(group.getId()); } protected <T> Set<T> set(T... objs) { return new HashSet<T>(asList(objs)); } protected <T> Set<T> set(Iterable<T> objs) { return IteratorUtil.addToCollection(objs, new HashSet<T>()); } protected Node andresNode() { return template.getNode(andres.getId()); } protected Node emilNode() { return template.getNode(emil.getId()); } public Person readPerson(Node node) { return entityPersister.read(Person.class, node); } protected Relationship makeFriends(Node from, Node to, int years) { Relationship friendship = from.createRelationshipTo(to, KNOWS); friendship.setProperty("Friendship.years", years); return friendship; } public Group readGroup(Node node) { return entityPersister.read(Group.class, node); } protected List<Node> getRelatedNodes(Node startNode, String type, Direction direction) { List<Node> result = new ArrayList<Node>(); for (Relationship relationship : startNode.getRelationships(DynamicRelationshipType.withName(type), direction)) { result.add(relationship.getOtherNode(startNode)); } return result; } }