Search in sources :

Example 6 with MappedRelationship

use of org.neo4j.ogm.context.MappedRelationship in project neo4j-ogm by neo4j.

the class CompilerTest method shouldCorrectlyRemoveRelationshipWhenItemIsMovedToDifferentCollection.

@Test
public void shouldCorrectlyRemoveRelationshipWhenItemIsMovedToDifferentCollection() {
    Long teacherId = 0L;
    Long businessStudiesCourseId = 1L;
    Long designTechnologyCourseId = 2L;
    Long shivaniId = 3L;
    Course designTech = new Course("GCSE Design & Technology");
    designTech.setId(designTechnologyCourseId);
    Course businessStudies = new Course("GNVQ Business Studies");
    businessStudies.setId(businessStudiesCourseId);
    Teacher msThompson = new Teacher();
    msThompson.setId(teacherId);
    msThompson.setName("Ms Thompson");
    msThompson.setCourses(Arrays.asList(businessStudies, designTech));
    Student shivani = new Student("Shivani");
    shivani.setId(shivaniId);
    mappingContext.addNodeEntity(msThompson);
    mappingContext.addNodeEntity(businessStudies);
    mappingContext.addNodeEntity(designTech);
    mappingContext.addNodeEntity(shivani);
    mappingContext.addRelationship(new MappedRelationship(teacherId, "COURSES", businessStudiesCourseId, null, Teacher.class, Course.class));
    mappingContext.addRelationship(new MappedRelationship(teacherId, "COURSES", designTechnologyCourseId, null, Teacher.class, Course.class));
    mappingContext.addRelationship(new MappedRelationship(businessStudiesCourseId, "STUDENTS", shivaniId, null, Teacher.class, Student.class));
    // move shivani from one course to the other
    businessStudies.setStudents(Collections.emptyList());
    designTech.setStudents(Arrays.asList(shivani));
    // Save msThomson
    // we expect a new relationship to be created, and an old one deleted
    Compiler compiler = mapAndCompile(msThompson, -1);
    List<Statement> statements = compiler.createNodesStatements();
    assertThat(statements).isEmpty();
    statements = compiler.createRelationshipsStatements();
    assertThat(statements).extracting(Statement::getStatement).containsOnly("UNWIND $rows as row MATCH (startNode) WHERE ID(startNode) = row.startNodeId WITH row,startNode MATCH (endNode) WHERE ID(endNode) = row.endNodeId MERGE (startNode)-[rel:`STUDENTS`]->(endNode) RETURN row.relRef as ref, ID(rel) as id, $type as type");
    for (Statement statement : statements) {
        List rows = (List) statement.getParameters().get("rows");
        assertThat(rows).hasSize(1);
    }
    List<Statement> deleteRelsStatements = compiler.deleteRelationshipStatements();
    assertThat(deleteRelsStatements).extracting(Statement::getStatement).containsOnly("UNWIND $rows as row MATCH (startNode) WHERE ID(startNode) = row.startNodeId WITH row,startNode MATCH (endNode) WHERE ID(endNode) = row.endNodeId MATCH (startNode)-[rel:`STUDENTS`]->(endNode) DELETE rel");
    assertThat(((List) deleteRelsStatements.get(0).getParameters().get("rows"))).hasSize(1);
// fixme: these other tests now need to be in their own test method, because
// a bug fix to the deletion code means that a second deletion won't (correctly) fire again
// expect a delete, but don't expect the new relationship to be created, because the fact of it
// is inaccessible from the businessStudies object
// expectOnSave(businessStudies,
// "MATCH ($1)-[_0:STUDENTS]->($3) WHERE id($1)=1 AND id($3)=3 DELETE _0");
// 
// // expect the new relationship, but don't expect the old one to be deleted, because the fact
// // of it is inaccessible from the designTech object
// expectOnSave(designTech,
// "MATCH ($2) WHERE id($2)=2 MATCH ($3) WHERE id($3)=3 MERGE ($2)-[_0:`STUDENTS`]->($3) RETURN id(_0) AS _0");
// 
// // we can't explore the object model from shivani at all, so no changes.
// expectOnSave(shivani, "");
}
Also used : Statement(org.neo4j.ogm.request.Statement) MappedRelationship(org.neo4j.ogm.context.MappedRelationship) Teacher(org.neo4j.ogm.domain.education.Teacher) ArrayList(java.util.ArrayList) List(java.util.List) Course(org.neo4j.ogm.domain.education.Course) Student(org.neo4j.ogm.domain.education.Student) Test(org.junit.Test)

Example 7 with MappedRelationship

use of org.neo4j.ogm.context.MappedRelationship in project neo4j-ogm by neo4j.

the class CompilerTest method shouldDeleteExistingRelationshipEntity.

@Test
public void shouldDeleteExistingRelationshipEntity() {
    Long forumId = 0L;
    Long topicId = 1L;
    Long linkId = 2L;
    Forum forum = new Forum();
    forum.setId(forumId);
    forum.setName("Spring Data Neo4j");
    Topic topic = new Topic();
    topic.setTopicId(topicId);
    topic.setInActive(Boolean.FALSE);
    ForumTopicLink link = new ForumTopicLink();
    link.setId(linkId);
    link.setForum(forum);
    link.setTopic(topic);
    forum.setTopicsInForum(Arrays.asList(link));
    mappingContext.addNodeEntity(forum);
    mappingContext.addNodeEntity(topic);
    mappingContext.addRelationshipEntity(link, linkId);
    // the mapping context remembers the relationship between the forum and the topic in the graph
    mappingContext.addRelationship(new MappedRelationship(forumId, "HAS_TOPIC", topicId, null, Forum.class, ForumTopicLink.class));
    // unlink the objects manually
    forum.setTopicsInForum(null);
    link.setTopic(null);
    // expect the delete to be recognised when the forum is saved
    Compiler compiler = mapAndCompile(forum, -1);
    List<Statement> statements = compiler.createRelationshipsStatements();
    assertThat(statements).isEmpty();
    statements = compiler.deleteRelationshipStatements();
    assertThat(statements).extracting(Statement::getStatement).containsOnly("UNWIND $rows as row MATCH (startNode) WHERE ID(startNode) = row.startNodeId WITH row,startNode MATCH (endNode) WHERE ID(endNode) = row.endNodeId MATCH (startNode)-[rel:`HAS_TOPIC`]->(endNode) DELETE rel");
    assertThat(((List) statements.get(0).getParameters().get("rows"))).hasSize(1);
// expect the delete to be recognised if the RE is saved
// expectOnSave(link, "MATCH ($0)-[_0:HAS_TOPIC]->($1) WHERE id($0)=0 AND id($1)=1 DELETE _0");
// 
// // expect nothing to happen if the topic is saved, because the domain model does not
// // permit navigation from the topic to the RE (topic has no reference to it)
// expectOnSave(topic, "");
// todo: more tests re saving deletes from REs marked as incoming relationships
}
Also used : Statement(org.neo4j.ogm.request.Statement) MappedRelationship(org.neo4j.ogm.context.MappedRelationship) ForumTopicLink(org.neo4j.ogm.domain.forum.ForumTopicLink) Topic(org.neo4j.ogm.domain.forum.Topic) Forum(org.neo4j.ogm.domain.forum.Forum) Test(org.junit.Test)

Example 8 with MappedRelationship

use of org.neo4j.ogm.context.MappedRelationship in project neo4j-ogm by neo4j.

the class RequestExecutor method updateRelationships.

/**
 * Update the mapping context with new relationships created in a request.
 *
 * @param context        the compile context
 * @param relRefMappings mapping of relationship reference used in the compile context and the relationship id from the database
 */
private void updateRelationships(CompileContext context, List<ReferenceMapping> relRefMappings) {
    final Map<Long, TransientRelationship> registeredTransientRelationshipIndex = buildRegisteredTransientRelationshipIndex(context);
    for (ReferenceMapping referenceMapping : relRefMappings) {
        if (registeredTransientRelationshipIndex.containsKey(referenceMapping.ref)) {
            TransientRelationship transientRelationship = registeredTransientRelationshipIndex.get(referenceMapping.ref);
            boolean isRelationshipEntity = session.context().getRelationshipEntity(referenceMapping.id) != null;
            MappedRelationship mappedRelationship = new MappedRelationship(context.getId(transientRelationship.getSrc()), transientRelationship.getRel(), context.getId(transientRelationship.getTgt()), isRelationshipEntity ? referenceMapping.id : null, transientRelationship.getSrcClass(), transientRelationship.getTgtClass());
            session.context().addRelationship(mappedRelationship);
        }
    }
}
Also used : MappedRelationship(org.neo4j.ogm.context.MappedRelationship) TransientRelationship(org.neo4j.ogm.context.TransientRelationship)

Example 9 with MappedRelationship

use of org.neo4j.ogm.context.MappedRelationship in project neo4j-ogm by neo4j.

the class SaveEventDelegate method dirty.

// returns true if the object in question is dirty (has changed)
// an object is dirty if either or both of:
// - its properties have changed
// - its relationships has changed
private boolean dirty(Object parent) {
    // have any properties changed
    if (this.session.context().isDirty(parent)) {
        logger.debug("dirty: {}", parent);
        return true;
    }
    ClassInfo parentInfo = this.session.metaData().classInfo(parent);
    long parentId = session.context().nativeId(parent);
    // an RE cannot contain additional refs because hyperedges are forbidden in Neo4j
    if (!parentInfo.isRelationshipEntity()) {
        // build the set of mapped relationships for this object. if there any new ones, the object is dirty
        for (FieldInfo reader : relationalReaders(parent)) {
            clearPreviousRelationships(parentId, reader);
            for (MappedRelationship mappable : map(parentInfo, parentId, reader.read(parent), reader)) {
                if (isNew(mappable)) {
                    logger.debug("added new relationship: {} to {}", mappable, parent);
                    this.addedRelationships.add(mappable);
                    return true;
                }
                this.registeredRelationships.add(mappable);
                // no longer deleted
                this.deletedRelationships.remove(mappable);
            }
        }
        for (MappedRelationship previous : session.context().getRelationships()) {
            if (isDeleted(previous) && (previous.getStartNodeId() == parentId || previous.getEndNodeId() == parentId)) {
                logger.debug("deleted: {} from {}", previous, parent);
                return true;
            }
        }
    }
    return false;
}
Also used : MappedRelationship(org.neo4j.ogm.context.MappedRelationship) FieldInfo(org.neo4j.ogm.metadata.FieldInfo) ClassInfo(org.neo4j.ogm.metadata.ClassInfo)

Example 10 with MappedRelationship

use of org.neo4j.ogm.context.MappedRelationship in project neo4j-ogm by neo4j.

the class SaveEventDelegate method deregisterIncomingRelationship.

private void deregisterIncomingRelationship(Long id, String relationshipType, Class endNodeType) {
    Iterator<MappedRelationship> iterator = this.registeredRelationships.iterator();
    while (iterator.hasNext()) {
        MappedRelationship mappedRelationship = iterator.next();
        if (mappedRelationship.getEndNodeId() == id && mappedRelationship.getRelationshipType().equals(relationshipType) && endNodeType.equals(mappedRelationship.getStartNodeType())) {
            deletedRelationships.add(mappedRelationship);
            iterator.remove();
        }
    }
}
Also used : MappedRelationship(org.neo4j.ogm.context.MappedRelationship)

Aggregations

MappedRelationship (org.neo4j.ogm.context.MappedRelationship)18 Test (org.junit.Test)11 Statement (org.neo4j.ogm.request.Statement)9 Teacher (org.neo4j.ogm.domain.education.Teacher)4 RowStatementFactory (org.neo4j.ogm.session.request.RowStatementFactory)4 ArrayList (java.util.ArrayList)3 List (java.util.List)3 Compiler (org.neo4j.ogm.cypher.compiler.Compiler)3 School (org.neo4j.ogm.domain.education.School)3 Document (org.neo4j.ogm.domain.filesystem.Document)3 Folder (org.neo4j.ogm.domain.filesystem.Folder)3 HashSet (java.util.HashSet)2 Course (org.neo4j.ogm.domain.education.Course)2 Student (org.neo4j.ogm.domain.education.Student)2 Forum (org.neo4j.ogm.domain.forum.Forum)2 ForumTopicLink (org.neo4j.ogm.domain.forum.ForumTopicLink)2 Topic (org.neo4j.ogm.domain.forum.Topic)2 ClassInfo (org.neo4j.ogm.metadata.ClassInfo)2 Direction (org.neo4j.ogm.annotation.Relationship.Direction)1 EntityGraphMapper (org.neo4j.ogm.context.EntityGraphMapper)1