0

using hibernate with Java Spring, I have two database tables, Projects and ProjectNotes. Project can have many Notes.

@Entity
@Table(name="projects")
public class Project {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;    

    @OneToMany(mappedBy="project", cascade=CascadeType.ALL)
    private List<ProjectNote> projectNotes;
}

and I want to add a new note to the project. Clearly i can do this.

    Project project = projectRepository.findOne(id);
    ProjectNote pn = new ProjectNote();
    pn.setText("Hello");
    pn.setProject(project);
    project.getProjectNotes().add(pn);
    projectRepository.save(project);

and it works. Is that any different than using the notes repository instead

    Project project = projectRepository.findOne(id);
    ProjectNote pn = new ProjectNote();
    pn.setText("Hello");
    pn.setProject(project);
    projectNotesRepository.save(pn);

Is either more efficient or more correct than the other?

EDIT: another thought. I'm also using @LastModifiedBy/Date on the project. I guess the first method will alter the project lastModified information, whilst the second method will not. But I have not tried it!

John Henckel
  • 10,274
  • 3
  • 79
  • 79
  • I'm uncertain whether Spring changes the picture, but for JPA in general, the application is responsible for maintaining the consistency of bidirectional relationships between entities in memory. Your first approach does so; your second approach does not. The latter is therefore inherently buggy, though whether the bug has an observable effect depends on how you go on to use the entities involved. – John Bollinger Jun 30 '17 at 21:38
  • 1
    Additionally, I am uncertain whether to expect `projectRepository.save(project);` to trigger an update of the project's modification date when nothing has changed about it but its notes, given that `ProjectNote` is the owner of the relationship involved. I suspect not. This would be something to test. In fact, you should have an *automated* test for it in your test suite. – John Bollinger Jun 30 '17 at 21:43

1 Answers1

1

In a bidirectional mapping the application is expected to keep the values in sync, meaning that if you call bar.setProject(foo) that method is expected to call foo.getNotes().add(this), making the operations symmetric.

If you enable query logging on Hibernate, you'll see that the end result is the same. The last modified date will also be updated in both cases of course.

Here are some good additional considerations about the complexities of bidirectional associations (and why you might want to avoid them): What is the difference between Unidirectional and Bidirectional associations?

Kayaman
  • 72,141
  • 5
  • 83
  • 121