use of org.neo4j.ogm.model.Edge in project neo4j-ogm by neo4j.
the class GraphEntityMapper method mapOneToMany.
private void mapOneToMany(Collection<Edge> oneToManyRelationships) {
EntityCollector entityCollector = new EntityCollector();
List<MappedRelationship> relationshipsToRegister = new ArrayList<>();
// first, build the full set of related entities of each type and direction for each source entity in the relationship
for (Edge edge : oneToManyRelationships) {
Object instance = mappingContext.getNodeEntity(edge.getStartNode());
Object parameter = mappingContext.getNodeEntity(edge.getEndNode());
// is this a relationship entity we're trying to map?
Object relationshipEntity = mappingContext.getRelationshipEntity(edge.getId());
if (relationshipEntity != null) {
// establish a relationship between
FieldInfo outgoingWriter = findIterableWriter(instance, relationshipEntity, edge.getType(), Direction.OUTGOING);
if (outgoingWriter != null) {
entityCollector.collectRelationship(edge.getStartNode(), DescriptorMappings.getType(outgoingWriter.getTypeDescriptor()), edge.getType(), Direction.OUTGOING, edge.getId(), edge.getEndNode(), relationshipEntity);
relationshipsToRegister.add(new MappedRelationship(edge.getStartNode(), edge.getType(), edge.getEndNode(), edge.getId(), instance.getClass(), DescriptorMappings.getType(outgoingWriter.getTypeDescriptor())));
}
FieldInfo incomingWriter = findIterableWriter(parameter, relationshipEntity, edge.getType(), Direction.INCOMING);
if (incomingWriter != null) {
entityCollector.collectRelationship(edge.getEndNode(), DescriptorMappings.getType(incomingWriter.getTypeDescriptor()), edge.getType(), Direction.INCOMING, edge.getId(), edge.getStartNode(), relationshipEntity);
relationshipsToRegister.add(new MappedRelationship(edge.getStartNode(), edge.getType(), edge.getEndNode(), edge.getId(), instance.getClass(), DescriptorMappings.getType(incomingWriter.getTypeDescriptor())));
}
} else {
// Use getRelationalWriter instead of findIterableWriter
// findIterableWriter will return matching iterable even when there is better matching single field
FieldInfo outgoingWriter = getRelationalWriter(metadata.classInfo(instance), edge.getType(), Direction.OUTGOING, parameter);
if (outgoingWriter != null) {
if (!outgoingWriter.forScalar()) {
entityCollector.collectRelationship(edge.getStartNode(), DescriptorMappings.getType(outgoingWriter.getTypeDescriptor()), edge.getType(), Direction.OUTGOING, edge.getEndNode(), parameter);
} else {
outgoingWriter.write(instance, parameter);
}
MappedRelationship mappedRelationship = new MappedRelationship(edge.getStartNode(), edge.getType(), edge.getEndNode(), null, instance.getClass(), DescriptorMappings.getType(outgoingWriter.getTypeDescriptor()));
relationshipsToRegister.add(mappedRelationship);
}
FieldInfo incomingWriter = getRelationalWriter(metadata.classInfo(parameter), edge.getType(), Direction.INCOMING, instance);
if (incomingWriter != null) {
if (!incomingWriter.forScalar()) {
entityCollector.collectRelationship(edge.getEndNode(), DescriptorMappings.getType(incomingWriter.getTypeDescriptor()), edge.getType(), Direction.INCOMING, edge.getStartNode(), instance);
} else {
incomingWriter.write(parameter, instance);
}
relationshipsToRegister.add(new MappedRelationship(edge.getStartNode(), edge.getType(), edge.getEndNode(), null, instance.getClass(), DescriptorMappings.getType(incomingWriter.getTypeDescriptor())));
}
}
}
entityCollector.forCollectedEntities((sourceId, type, direction, targetType, entities) -> mapOneToMany(mappingContext.getNodeEntity(sourceId), targetType, entities, type, direction));
// now register all the relationships we've mapped as iterable types into the mapping context
for (MappedRelationship mappedRelationship : relationshipsToRegister) {
mappingContext.addRelationship(mappedRelationship);
}
}
use of org.neo4j.ogm.model.Edge in project neo4j-ogm by neo4j.
the class MultiStatementCypherCompiler method deleteRelationshipEntityStatements.
@Override
public List<Statement> deleteRelationshipEntityStatements() {
assertStatementFactoryExists();
// Group relationships by type
Map<String, Set<Edge>> deletedRelsByType = groupRelationshipsByType(deletedRelationshipEntityBuilders);
List<Statement> statements = new ArrayList<>();
for (Set<Edge> edges : deletedRelsByType.values()) {
DeletedRelationshipEntityStatementBuilder deletedRelationshipBuilder = new DeletedRelationshipEntityStatementBuilder(edges, statementFactory);
statements.add(deletedRelationshipBuilder.build());
}
return statements;
}
use of org.neo4j.ogm.model.Edge in project neo4j-ogm by neo4j.
the class DeletedRelationshipEntityStatementBuilder method build.
@Override
public Statement build() {
final Map<String, Object> parameters = new HashMap<>();
final StringBuilder queryBuilder = new StringBuilder();
if (deletedEdges != null && deletedEdges.size() > 0) {
Edge firstEdge = deletedEdges.iterator().next();
queryBuilder.append("UNWIND $rows AS row MATCH ()-[r]->() WHERE ID(r) = row.relId ");
if (firstEdge.hasVersionProperty()) {
queryBuilder.append(OptimisticLockingUtils.getFragmentForExistingNodesAndRelationships(firstEdge, "r"));
}
queryBuilder.append("DELETE r RETURN ID(r) as ref, ID(r) as id, $type as type");
List<Map> rows = new ArrayList<>();
for (Edge edge : deletedEdges) {
Map<String, Object> rowMap = new HashMap<>();
rowMap.put("relId", edge.getId());
if (edge.hasVersionProperty()) {
Property version = edge.getVersion();
rowMap.put((String) version.getKey(), version.getValue());
}
rows.add(rowMap);
}
parameters.put("rows", rows);
parameters.put("type", "rel");
if (firstEdge.hasVersionProperty()) {
OptimisticLockingConfig olConfig = new OptimisticLockingConfig(rows.size(), new String[] { firstEdge.getType() }, firstEdge.getVersion().getKey());
return statementFactory.statement(queryBuilder.toString(), parameters, olConfig);
}
}
return statementFactory.statement(queryBuilder.toString(), parameters);
}
use of org.neo4j.ogm.model.Edge in project neo4j-ogm by neo4j.
the class NewRelationshipStatementBuilder method build.
@Override
public Statement build() {
final Map<String, Object> parameters = new HashMap<>();
final StringBuilder queryBuilder = new StringBuilder();
boolean hasProperties = false;
if (edges != null && edges.size() > 0) {
Edge firstEdge = edges.iterator().next();
String relType = firstEdge.getType();
hasProperties = firstEdge.getPropertyList().size() > 0;
boolean hasPrimaryId = firstEdge.getPrimaryIdName() != null;
queryBuilder.append("UNWIND $rows as row ").append("MATCH (startNode) WHERE ID(startNode) = row.startNodeId WITH row,startNode ").append("MATCH (endNode) WHERE ID(endNode) = row.endNodeId ");
if (hasProperties && !hasPrimaryId) {
queryBuilder.append("CREATE ");
} else {
queryBuilder.append("MERGE ");
}
queryBuilder.append("(startNode)-[rel:`").append(relType).append("`");
if (hasPrimaryId) {
queryBuilder.append(" {`").append(firstEdge.getPrimaryIdName()).append("`: row.props.`").append(firstEdge.getPrimaryIdName()).append("`}");
}
queryBuilder.append("]->(endNode) ");
if (hasProperties) {
queryBuilder.append("SET rel += row.props ");
}
queryBuilder.append("RETURN row.relRef as ref, ID(rel) as id, $type as type");
List<Map> rows = new ArrayList<>();
for (Edge edge : edges) {
Map<String, Object> rowMap = new HashMap<>();
rowMap.put("startNodeId", edge.getStartNode());
rowMap.put("endNodeId", edge.getEndNode());
rowMap.put("relRef", edge.getId());
if (hasProperties) {
Map<String, Object> props = new HashMap<>();
for (Property property : edge.getPropertyList()) {
props.put((String) property.getKey(), property.getValue());
}
rowMap.put("props", props);
} else {
// need to put empty map here for simple relationships to avoid Cypher error because
// props is used in the query
rowMap.put("props", emptyMap());
}
rows.add(rowMap);
}
parameters.put("type", "rel");
parameters.put("rows", rows);
}
return statementFactory.statement(queryBuilder.toString(), parameters);
}
use of org.neo4j.ogm.model.Edge in project neo4j-ogm by neo4j.
the class GraphEntityMapper method mapRelationships.
private Set<Long> mapRelationships(GraphModel graphModel) {
Set<Long> mappedRelationshipIds = new HashSet<>();
List<Edge> oneToMany = new ArrayList<>();
for (Edge edge : graphModel.getRelationships()) {
Object source = mappingContext.getNodeEntity(edge.getStartNode());
Object target = mappingContext.getNodeEntity(edge.getEndNode());
if (source == null || target == null) {
String messageFormat = "Relationship {} cannot be fully hydrated because one or more required node entities have not been part of the result set.";
logger.warn(messageFormat, edge);
} else {
mappedRelationshipIds.add(edge.getId());
// check whether this edge should in fact be handled as a relationship entity
ClassInfo relationshipEntityClassInfo = getRelationshipEntity(edge);
if (relationshipEntityClassInfo != null) {
mapRelationshipEntity(oneToMany, edge, source, target, relationshipEntityClassInfo);
} else {
oneToMany.add(edge);
}
}
}
if (!oneToMany.isEmpty()) {
mapOneToMany(oneToMany);
}
return mappedRelationshipIds;
}
Aggregations