Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
05-23-2020 06:57 PM
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?
05-26-2020 11:20 PM
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.
All the sessions of the conference are now available online