Query isn't filtering properly when made within the scope of @Transactional

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);
}

You are absolutely right with your assumption.
Within one transaction one Session will get created with a caching mechanism. When you query for the very same Student, Neo4j-OGM will just add / modify the data on the loaded object but not discard any that is not included in the result.
You could inject the SessionFactory instead of the Session and explicitly open a new Session for the test data setup.
ps. I have the feeling that I answered this somewhere else already around last week.