cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

Cyclic issues with SpringBoot for Neo4j Nodes and Relationship persistence

Hey there,
I am trying to learn Neo4j with SpringBoot and I am facing issues creating relationships.

First I thought if I update a Persistent object, it will automatically trigger a state change in the graph. It's not happening. When I try to do a save again on the entity, I am getting stackoverflow issue because one entity is connected to another which again has a relationship defined to the original entity.

I am working with Movies graph. Basically trying to develop rest endpoints to persist new movies and Person and the Relationship between them. My code is throwing stackoverflow issue when i try to save the relationships.

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class MovieDto {
	// movie properties
	private Long id;
	private String title;
	private int released;
	private String tagline;
	
	// relationship -> Person 
	private List<PersonDto> actedIn;
}
@Repository
public interface MovieRepository extends Neo4jRepository<MovieEntity, Long> {
    // save
    @Query("Merge(m: Movie {title: $title, released: $released, tagline: $tagline}) "
    		+ " ON CREATE SET m.roles = [] "
    		+ " return m ")
    public MovieEntity mergeSave(
    		@Param("title") String title,
    		@Param("released") int released,
    		@Param("tagline") String tagline
    );
}
@NodeEntity(label="Person")
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class PersonEntity {
	@Id
	@GeneratedValue
	private Long id;
	private String name;
	private int born;

	@Relationship(type = "ACTED_IN")
	private List<MovieEntity> movies;
	
	public void addMovie(MovieEntity movie) {
		if(this.movies == null) {
			this.movies = new ArrayList<MovieEntity>();
		}
		this.movies.add(movie);
	}
}
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@NodeEntity(label="Movie")
public class MovieEntity {
    @Id
    @GeneratedValue
    private Long id;
    private String title;
    private int released;
    private String tagline;

    @Relationship(type = "ACTED_IN", direction = Relationship.INCOMING)
    @JsonIgnore
    private List<RoleEntity> roles;
}
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@RelationshipEntity(type = "ACTED_IN")
public class RoleEntity {
    @Id
    @GeneratedValue
    private Long id;
    
    @StartNode
    private PersonEntity person;
    @EndNode
    private MovieEntity movie;

    public void addRoleName(String name) {
        if (this.roles == null) {
            this.roles = new ArrayList<>();
        }
        this.roles.add(name);
    }
}
public MovieEntity saveMovie(MovieDto movie) {
		// save
		MovieEntity movieEntity = movieRepository.mergeSave(
				movie.getTitle(), 
				movie.getReleased(), 
				movie.getTagline()
		);
		
		List<PersonEntity> actorsList = new ArrayList<>();
		if(movieEntity.getRoles() == null) {
			movieEntity.setRoles(new ArrayList<RoleEntity>());
		}
		List<RoleEntity> roles = movieEntity.getRoles();
		
		for(PersonDto person: movie.getActedIn()) {
			PersonEntity personEntity = personRepository.mergeSave(person.getName(), person.getBorn());
			personEntity.addMovie(movieEntity);
			
			roles.add(
					RoleEntity.builder()
					.movie(movieEntity)
					.person(personEntity) 
					.build()
					);
			actorsList.add(personEntity);
		}
		
		movieEntity.setRoles(roles);
		
                // issue in this line (cyclic)
		movieRepository.save(movieEntity);
		
		return movieEntity;
	}

Can someone please help me understand how to do this?

1 REPLY 1

Welcome to the Neo4j community.
In general your assumption is right: When you persist the MovieEntity everything attached to it should get also saved to the graph. You did not provide the exception log but I assume that the problem might be rooted in the usage of the repositories and the transaction boundaries.
If you do not use Spring's @Transactional annotation around your unit of work, every call to the repository will create a new transaction and -in the background- a new Neo4j-OGM Session with its own cache. So it is very likely that this is the reason for not seeing the right changes to the graph.
Regarding the stackoverflow I would need to see the logs.

Also if you just have started to work with Neo4j and Spring Boot (and Spring Data Neo4j), I recommend to use Spring Data Neo4j RX (https://github.com/neo4j/sdn-rx/). It will be the successor of Spring Data Neo4j in the future.