2

I have the following Springboot code:

Comment.java

@Entity
@Getter @Setter @NoArgsConstructor @RequiredArgsConstructor
public class Comment extends Auditable {

    @Id
    @GeneratedValue
    private Long id;

    @NonNull
    private String comment;

    @ManyToOne(fetch = FetchType.LAZY)
    private Link link;
}

Link.java

@Entity
@Getter @Setter @NoArgsConstructor @RequiredArgsConstructor
public class Link extends Auditable {

    @Id
    @GeneratedValue
    private Long id;

    @NonNull
    private String title;

    @NonNull
    private String url;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "link")
    private List<Comment> comments = new ArrayList<>();

    public void addComment(Comment c) {
        comments.add(c);
    }
}

And the following Runner:

 @Bean
 CommandLineRunner someRunner(LinkRepository lr, CommentRepository cr) {
     return args -> {
         Link link = new Link("Getting started", "url");
         Comment c = new Comment("Hello!");
         link.addComment(c);
         linkRepository.save(link);
     };
 };

I am trying for the comment to be linked to the link, and both to save together. However, this is the output:

[
    {
        createdBy: null,
        createdDate: "2/28/19, 11:48 PM",
        lastModifiedBy: null,
        lastModifiedDate: "2/28/19, 11:48 PM",
        id: 2,
        comment: "Hello!",
        link: null
    }
]

Any advice on how I can get the link to actually show in the list of links?

buræquete
  • 14,226
  • 4
  • 44
  • 89
MrD
  • 4,986
  • 11
  • 48
  • 90

1 Answers1

2

In a bidirectional relationship, you have to set both sides of the relationship;

Link link = new Link("Getting started", "url");
Comment comment = new Comment("Hello!");
comment.setLink(link);  // missing in your code
link.addComment(comment);
linkRepository.save(link);

Check "Bidirectional Many-to-One Associations" > here

buræquete
  • 14,226
  • 4
  • 44
  • 89
  • Hi, Thanks, I was under the impression that CascadeType.ALL would apply to the associated entities as well (ie: the comment)? From here: https://stackoverflow.com/a/13027444/1876047 – MrD Mar 01 '19 at 12:48
  • I see, I would have thought that because I had the mappedBy parameter in the annotation that would have been done automatically, but it seems not to. Is there some way to configure it so that when I add a comment to the link it automatically also adds the link to the comment? I suppose I could do something like comment.setLink(this) in the addComment method but I was hoping for some automatic config allowing SpringBoot to pick it up automatically – MrD Mar 01 '19 at 12:56
  • @MrD I have the exact thinking, but not sure why it is not there. Must be that there is some case where it breaks the overlying persistence logic maybe? Seems very trivial, yet we need to be explicit and do it manually... We had 50 tables connected to a single parent table, within a 5 step deep hierarchy. Can you imagine the horror? I've created a whole automated generic entity structure to handle it as you are suggesting =P – buræquete Mar 01 '19 at 12:59
  • 1
    Makes sense thanks, for now I just added comment.setLink(this); in the addComment method and it seems to work. Thanks for your help! – MrD Mar 01 '19 at 13:01