/** * Fetch relationships for the given source node. * * @param sourceNode * @param relType can be null * @param dir * @return a list of relationships * @throws FrameworkException */ public List<AbstractRelationship> execute( AbstractNode sourceNode, RelationshipType relType, Direction dir) throws FrameworkException { RelationshipFactory factory = new RelationshipFactory(securityContext); List<AbstractRelationship> result = new LinkedList<AbstractRelationship>(); Node node = sourceNode.getNode(); Iterable<Relationship> rels; if (node == null) { return Collections.EMPTY_LIST; } if (relType != null) { rels = node.getRelationships(relType, dir); } else { rels = node.getRelationships(dir); } try { for (Relationship r : rels) { result.add(factory.instantiate(r)); } } catch (RuntimeException e) { logger.log(Level.WARNING, "Exception occured: ", e.getMessage()); /** * ********* FIXME * * <p>Here an exception occurs: * * <p>org.neo4j.kernel.impl.nioneo.store.InvalidRecordException: Node[5] is neither * firstNode[37781] nor secondNode[37782] for Relationship[188125] at * org.neo4j.kernel.impl.nioneo.xa.ReadTransaction.getMoreRelationships(ReadTransaction.java:131) * at * org.neo4j.kernel.impl.nioneo.xa.NioNeoDbPersistenceSource$ReadOnlyResourceConnection.getMoreRelationships(NioNeoDbPersistenceSource.java:280) * at * org.neo4j.kernel.impl.persistence.PersistenceManager.getMoreRelationships(PersistenceManager.java:100) * at org.neo4j.kernel.impl.core.NodeManager.getMoreRelationships(NodeManager.java:585) at * org.neo4j.kernel.impl.core.NodeImpl.getMoreRelationships(NodeImpl.java:358) at * org.neo4j.kernel.impl.core.IntArrayIterator.hasNext(IntArrayIterator.java:115) */ } return result; }
@Override public void execute(Map<String, Object> attributes) throws FrameworkException { final String entityType = (String) attributes.get("type"); final String relType = (String) attributes.get("relType"); final GraphDatabaseService graphDb = (GraphDatabaseService) arguments.get("graphDb"); final SecurityContext superUserContext = SecurityContext.getSuperUserInstance(); final NodeFactory nodeFactory = new NodeFactory(superUserContext); final RelationshipFactory relFactory = new RelationshipFactory(superUserContext); if (entityType != null) { final Class type = EntityContext.getEntityClassForRawType(entityType); if (type != null) { // final Result<AbstractNode> result = Services.command(securityContext, // SearchNodeCommand.class).execute(true, false, Search.andExactType(type.getSimpleName())); final Result<AbstractNode> result = nodeFactory.instantiateAll(GlobalGraphOperations.at(graphDb).getAllNodes()); final List<AbstractNode> nodes = new ArrayList<AbstractNode>(); for (AbstractNode node : result.getResults()) { if (node.getClass().equals(type)) { nodes.add(node); } } logger.log( Level.INFO, "Start (re-)indexing all nodes of type {0}", new Object[] {type.getSimpleName()}); long count = bulkGraphOperation( securityContext, nodes, 1000, "RebuildIndex", new BulkGraphOperation<AbstractNode>() { @Override public void handleGraphObject( SecurityContext securityContext, AbstractNode node) { node.updateInIndex(); } @Override public void handleThrowable( SecurityContext securityContext, Throwable t, AbstractNode node) { logger.log( Level.WARNING, "Unable to index node {0}: {1}", new Object[] {node, t.getMessage()}); } @Override public void handleTransactionFailure( SecurityContext securityContext, Throwable t) { logger.log(Level.WARNING, "Unable to index node: {0}", t.getMessage()); } }); logger.log(Level.INFO, "Done with (re-)indexing {0} nodes", count); return; } } else if (relType != null) { // final Result<AbstractNode> result = Services.command(securityContext, // SearchNodeCommand.class).execute(true, false, Search.andExactType(type.getSimpleName())); final List<AbstractRelationship> unfilteredRels = relFactory.instantiate(GlobalGraphOperations.at(graphDb).getAllRelationships()); final List<AbstractRelationship> rels = new ArrayList<AbstractRelationship>(); for (AbstractRelationship rel : unfilteredRels) { if (!rel.getType().equals(relType)) { rels.add(rel); } } logger.log(Level.INFO, "Start setting UUID on all rels of type {0}", new Object[] {relType}); long count = bulkGraphOperation( securityContext, rels, 1000, "SetRelationshipUuid", new BulkGraphOperation<AbstractRelationship>() { @Override public void handleGraphObject( SecurityContext securityContext, AbstractRelationship rel) { rel.updateInIndex(); } @Override public void handleThrowable( SecurityContext securityContext, Throwable t, AbstractRelationship rel) { logger.log( Level.WARNING, "Unable to index relationship {0}: {1}", new Object[] {rel, t.getMessage()}); } @Override public void handleTransactionFailure(SecurityContext securityContext, Throwable t) { logger.log(Level.WARNING, "Unable to index relationship: {0}", t.getMessage()); } }); logger.log(Level.INFO, "Done with (re-)indexing {0} relationships", count); return; } logger.log(Level.INFO, "Unable to determine entity type to re-index."); }
private synchronized < A extends NodeInterface, B extends NodeInterface, R extends Relation<A, B, ?, ?>> R createRelationship( final A fromNode, final B toNode, final Class<R> relType, final PropertyMap properties) throws FrameworkException { final RelationshipFactory<R> factory = new RelationshipFactory(securityContext); final R template = instantiate(relType); final Node startNode = fromNode.getNode(); final Node endNode = toNode.getNode(); final Relationship rel = startNode.createRelationshipTo(endNode, template); final R newRel = factory.instantiate(rel); final Date now = new Date(); // logger.log(Level.INFO, "CREATING relationship {0}-[{1}]->{2}", new Object[] { // fromNode.getType(), newRel.getRelType(), toNode.getType() } ); if (newRel != null) { newRel.unlockReadOnlyPropertiesOnce(); newRel.setProperty(GraphObject.type, relType.getSimpleName()); // set UUID newRel.unlockReadOnlyPropertiesOnce(); newRel.setProperty(GraphObject.id, getNextUuid()); // set created date newRel.unlockReadOnlyPropertiesOnce(); newRel.setProperty(AbstractRelationship.createdDate, now); // set last modified date newRel.unlockReadOnlyPropertiesOnce(); newRel.setProperty(AbstractRelationship.lastModifiedDate, now); // Try to get the cascading delete flag from the domain specific relationship type newRel.unlockReadOnlyPropertiesOnce(); newRel.setProperty( AbstractRelationship.cascadeDelete, factory.instantiate(rel).getCascadingDeleteFlag()); // notify transaction handler TransactionCommand.relationshipCreated(newRel); if (properties != null) { for (Entry<PropertyKey, Object> entry : properties.entrySet()) { PropertyKey key = entry.getKey(); // on creation, writing of read-only properties should be possible if (key.isReadOnly() || key.isWriteOnce()) { newRel.unlockReadOnlyPropertiesOnce(); } newRel.setProperty(entry.getKey(), entry.getValue()); } } // notify relationship of its creation newRel.onRelationshipCreation(); // iterate post creation transformations for (Transformation<GraphObject> transformation : StructrApp.getConfiguration().getEntityCreationTransformations(newRel.getClass())) { transformation.apply(securityContext, newRel); } } return newRel; }