Hot questions for Using Neo4j in hibernate

Question:

Here's MVCE: https://github.com/neo4j-examples/movies-java-spring-data-neo4j

I added to Person entity method:

public void addMovie(Movie movie) {
    if (this.movies == null) {
        this.movies = new ArrayList<>();
    }
    this.movies.add(movie);
}

In test i added: In the setup:

    keanu.addMovie(matrix);
    personRepository.save(keanu);

In one of tests:

Person p = personRepository.findByName("Keanu Reeves");

In debug mode here i clearlly see that p has movies collection when fetched.

After changing code from github test it looks like this:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Transactional
public class MovieRepositoryTest {
    @Autowired
    private MovieRepository movieRepository;

    @Autowired
    private PersonRepository personRepository;

    @Before
    public void setUp() {
        Movie matrix = new Movie("The Matrix", 1999, "Welcome to the Real World");

        movieRepository.save(matrix);
        Person keanu = new Person("Keanu Reeves", 1964);
        personRepository.save(keanu);
        Role neo = new Role(matrix, keanu);
        neo.addRoleName("Neo");
        matrix.addRole(neo);
        keanu.addMovie(matrix);
        personRepository.save(keanu);
        movieRepository.save(matrix);
    }

    /**
     * Test of findByTitle method, of class MovieRepository.
     */
    @Test
    public void testFindByTitle() {

        String title = "The Matrix";
        Movie result = movieRepository.findByTitle(title);
        Person p = personRepository.findByName("Keanu Reeves");

        assertNotNull(result);
        assertEquals(1999, result.getReleased());
    }

    /**
     * Test of findByTitleContaining method, of class MovieRepository.
     */
    @Test
    public void testFindByTitleContaining() {
        String title = "*Matrix*";
        Collection<Movie> result = movieRepository.findByTitleLike(title);
        assertNotNull(result);
        assertEquals(1, result.size());
    }

    /**
     * Test of graph method, of class MovieRepository.
     */
    @Test
    public void testGraph() {
        Collection<Movie> graph = movieRepository.graph(5);

        assertEquals(1, graph.size());

        Movie movie = graph.iterator().next();

        assertEquals(1, movie.getRoles().size());

        assertEquals("The Matrix", movie.getTitle());
        assertEquals("Keanu Reeves", movie.getRoles().iterator().next().getPerson().getName());
    }
}

But if i make this:

  @Bean
    CommandLineRunner demo(PersonRepository personRepository, MovieRepository movieRepository) {
        return args -> {
        personRepository.deleteAll();
        movieRepository.deleteAll();

        Movie matrix = new Movie("The Matrix", 1999, "Welcome to the Real World");

        movieRepository.save(matrix);

        Person keanu = new Person("Keanu Reeves", 1964);

        personRepository.save(keanu);

        Role neo = new Role(matrix, keanu);
        neo.addRoleName("Neo");

        matrix.addRole(neo);

        keanu.addMovie(matrix);
        personRepository.save(keanu);

        movieRepository.save(matrix);


        Movie result = movieRepository.findByTitle("The Matrix");
        Person p = personRepository.findByName("Keanu Reeves");
    };
}

I see that p has not any movies. Why the difference? The code is the same as in test.


Answer:

I am not familiar with neo4j however would guess that it the fact that the test runs in a @Transaction and the code executed by command line runner does not.

Therefore remove the logic from command line runner to some place where it can be wrapped in a transaction, either a service class or application listener.