use of org.neo4j.ogm.annotation.Relationship.Direction in project neo4j-ogm by neo4j.
the class EntityGraphMapper method mapEntityReferences.
/**
* Finds all the objects that can be mapped via relationships from the object 'entity' and
* links them in the graph.
* This includes objects that are directly linked, as well as objects linked via a relationship entity
*
* @param entity the node whose relationships will be updated
* @param nodeBuilder a {@link NodeBuilder} that knows how to create node create/update cypher phrases
* @param horizon the depth in the tree. If this reaches 0, we stop mapping any deeper
*/
private void mapEntityReferences(final Object entity, NodeBuilder nodeBuilder, int horizon) {
int depth = currentDepth.incrementAndGet();
LOGGER.debug("mapping references declared by: {}, currently at depth {}", entity, depth);
ClassInfo srcInfo = metaData.classInfo(entity);
Long srcIdentity = mappingContext.nativeId(entity);
for (FieldInfo reader : srcInfo.relationshipFields()) {
String relationshipType = reader.relationshipType();
Direction relationshipDirection = reader.relationshipDirection();
Class startNodeType = srcInfo.getUnderlyingClass();
Class endNodeType = DescriptorMappings.getType(reader.getTypeDescriptor());
LOGGER.debug("{}: mapping reference type: {}", entity, relationshipType);
DirectedRelationship directedRelationship = new DirectedRelationship(relationshipType, relationshipDirection);
CompileContext context = compiler.context();
if (srcIdentity >= 0) {
List<Class<?>> potentiallyRelated = new ArrayList<>();
potentiallyRelated.add(endNodeType);
ClassInfo endNodeTypeClassInfo = metaData.classInfo(endNodeType);
if (endNodeTypeClassInfo != null) {
endNodeTypeClassInfo.allSubclasses().stream().map(ClassInfo::getUnderlyingClass).forEach(potentiallyRelated::add);
}
boolean cleared = false;
for (Class<?> clazz : potentiallyRelated) {
if (clearContextRelationships(context, srcIdentity, clazz, directedRelationship)) {
cleared = true;
}
}
if (!cleared) {
LOGGER.debug("this relationship is already being managed: {}-{}-{}-()", entity, relationshipType, relationshipDirection);
continue;
}
}
Object relatedObject = reader.read(entity);
if (relatedObject != null) {
if (isRelationshipEntity(relatedObject)) {
ClassInfo declaredObjectInfo = metaData.classInfo(relationshipType);
if (declaredObjectInfo.isAbstract()) {
final ClassInfo relatedObjectClassInfo = metaData.classInfo(relatedObject);
if (!relatedObjectClassInfo.neo4jName().equals(directedRelationship.type())) {
directedRelationship = new DirectedRelationship(relatedObjectClassInfo.neo4jName(), directedRelationship.direction());
relationshipType = directedRelationship.type();
}
}
}
RelationshipNodes relNodes = new RelationshipNodes(entity, null, startNodeType, endNodeType);
relNodes.sourceId = srcIdentity;
Boolean mapBothWays = null;
for (Object tgtObject : CollectionUtils.iterableOf(relatedObject)) {
if (tgtObject == null) {
throw new InvalidRelationshipTargetException(startNodeType, relationshipType, reader.getName(), endNodeType);
}
if (mapBothWays == null) {
mapBothWays = bothWayMappingRequired(entity, relationshipType, tgtObject, relationshipDirection);
}
relNodes.target = tgtObject;
link(directedRelationship, nodeBuilder, horizon, mapBothWays, relNodes);
}
}
}
currentDepth.decrementAndGet();
}
Aggregations