I have some code that within a transaction, creates a node and a list of edges and calls save(). I then query for the list of edges by a non-keyed field hoping to return one edge, however, the repository returns all the edges. Why is that? I have to call session.clear() before calling my repository query to get the filter to work properly. Is this because of the session cache or something?
@SpringBootTest()
@TestInstance(Lifecycle.PER_CLASS)
@ActiveProfiles(profiles = "embeddedTest")
public class UpdateEdgeTest {
@Autowired
private GraphRepositoryTestingHelper graphRepositoryTestingHelper;
@Autowired
private StudentRepository studentRepository;
@Autowired
private CourseRepository courseRepository;
@Autowired
private Session session;
public void setupData(){
Student expected = new Student();
expected.setFirstName("John");
expected.setLastName("Carter");
expected.setKey("naturalKey");
List<EnrolledIn> enrollment = new ArrayList<>();
EnrolledIn enrolledIn = new EnrolledIn()
.setCourse(new Course()
.setCourseName("neo4j101")
.setKey("n4j101-jan2020"))
.setSemester("Jan-2020")
.setStudent(expected);
EnrolledIn enrolledIn2 = new EnrolledIn()
.setCourse(new Course()
.setCourseName("java101")
.setKey("java101-2020"))
.setSemester("Jan-2020")
.setStudent(expected);
enrollment.add(enrolledIn);
enrollment.add(enrolledIn2);
expected.setEnrolledIn(enrollment);
final Student actual = studentRepository.save(expected);
}
@AfterAll //must use @AfterAll or else the nodes won't be deleted
public void after(){
graphRepositoryTestingHelper.deleteAllNodes();
}
@Test
@Transactional
public void shouldUpdateOneCourseAndAddNewOneLeavingExistingOnesUnchanged(){
// setupData() does not work properly.... for some reason attempting to save this data
// and then call the query findStudentForCourse within the same transaction will not filter out the enrolledIn edges.
setupData();
final Optional<Student> astudentWithTwoEdges = studentRepository.findById("naturalKey");
assertEquals(2, astudentWithTwoEdges.get().getEnrolledIn().size(), "should have 2 courses now");
// to fix, call session.clear().... not sure why.
//calling this makes the below query 'findStudentForCourse' work properly... I have no idea why.
//if this is not called, the query returns ALL the enrolledIn relationships......
session.clear();
//find one of the student edges
final Student studentForCourse = studentRepository.findStudentForCourse("naturalKey", "java101-2020");
assertEquals(1, studentForCourse.getEnrolledIn().size(), "should only be one due to query filter");
}
@Repository
public interface StudentRepository extends Neo4jRepository<Student, String> {
@Query("MATCH (student:Student { key: {key}})-[e:ENROLLED_IN]->(c:Course) "
+ "WHERE c.key = {`enrollmentId`} "
+ "RETURN student, e, c")
Student findStudentForCourse(@Param("key") String key, @Param("enrollmentId") String enrollmentId);
}