Как правильно сохранить отношение «один ко многим» ко многим

#java #hibernate #jpa #spring-data

Вопрос:

Я получаю

Вызвано: org.postgresql.util.PSQLException: ОШИБКА: нулевое значение в столбце «post_id» нарушает ограничение not-null

когда я пытаюсь настойчиво следовать за Сущностями. Связь-это одна запись со многими комментариями к публикациям, в которых есть еще много комментариев к публикациям. Я бы хотел, чтобы отношение также было однонаправленным, если это возможно. Можете ли вы указать, что я делаю не так?

SQL:

     CREATE TABLE post
    (
     id    BIGSERIAL PRIMARY KEY,
     title TEXT
    );

    CREATE TABLE post_comment
    (
     id      BIGSERIAL PRIMARY KEY,
     review  TEXT,
     post_id BIGINT NOT NULL,

     CONSTRAINT post_comment_fk FOREIGN KEY (post_id)
        REFERENCES post (id)
    );

    CREATE TABLE more_post_comment
    (
     id      BIGSERIAL PRIMARY KEY,
     another  TEXT,
     post_comment_id BIGINT NOT NULL,

     CONSTRAINT more_post_comment_fk FOREIGN KEY (post_comment_id)
        REFERENCES post_comment (id)
    );
 

Хранилище:

     @Repository
    public interface PostRepository extends JpaRepository<Post, Long> {
    }
 

Публикация:

     @Entity(name = "Post")
    @Table(name = "post")
    @Data
    public class Post {
 
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private String title;
 
        @OneToMany(cascade = CascadeType.ALL)
        @JoinColumn(name = "post_id")
        private List<PostComment> comments = new ArrayList<>();

     }
 

ПостКоммент:

     @Entity(name = "PostComment")
    @Table(name = "post_comment")
    @Data
    public class PostComment {
 
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private String review;

        @OneToMany(cascade = CascadeType.ALL)
        @JoinColumn(name = "post_comment_id")
        private List<MorePostComment> morePostComment = new ArrayList<>();
    }
 

Еще один посткоммент:

     @Entity(name = "MorePostComment")
    @Table(name = "more_post_comment")
    @Data
    public class MorePostComment {
 
       @Id
       @GeneratedValue(strategy = GenerationType.IDENTITY)
       private Long id;
       private String another;
   }
 

Тест:

 @SpringBootTest
class Test {

    @Autowired
    private PostRepository postRepository;

    @Test
    public void should() {

        Post post = new Post();
        post.setTitle("title");

        MorePostComment morePostComment = new MorePostComment();
        morePostComment.setAnother("another");

        List<MorePostComment> morePostComments = new ArrayList<>();
        morePostComments.add(morePostComment);

        PostComment postComment = new PostComment();
        postComment.setReview("asd");
        postComment.setMorePostComment(morePostComments);

        List<PostComment> comments = new ArrayList<>();
        comments.add(postComment);
        post.setComments(comments);

        post = postRepository.save(post);

        assertThat(post.getComments()).isNotEmpty();
        assertThat(post.getComments().get(0).getId()).isNotNull();
        assertThat(post.getComments().get(0).getMorePostComment()).isNotEmpty();

    }
}
 

Ответ №1:

Пожалуйста, добавьте nullable = false в свои @JoinColumn аннотации:

     @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "post_id", nullable = false)
    private List<PostComment> comments = new ArrayList<>();
 

и

     @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "post_comment_id", nullable = false)
    private List<MorePostComment> morePostComment = new ArrayList<>();
 

Подсказка: вам не нужна @Repository аннотация над вашей PostRepository , потому что она расширяется JpaRepostirory , и spring знает, что компонент репозитория должен быть создан.