正确使用单个@ManyToOne关联进行大小控制和分页

时间:2018-08-09 19:35:34

标签: java spring hibernate jpa spring-data-jpa

由于以下原因,我想避免“双向@OneToMany”关联:

  1. 它不能限制@OneToMany
  2. 的大小
  3. 我需要进行分页。

为此,我使用了this tutorial来描述“仅@ManyToOne”的关联,但不幸的是,它仅给出与此相关的一行代码:

List<PostComment> comments = entityManager.createQuery(
    "select pc " +
    "from PostComment pc " +
    "where pc.post.id = :postId", PostComment.class)
.setParameter( "postId", 1L )
.getResultList();

所以,我有很多问题:

  1. 我应该在哪里使用此行?

  2. 我应如何以及在何处获得EntityManager?确实在实体中?这是一个好的解决方案吗?

  3. 如何避免使用EntityManager?我已经看过this和其他问题,但是很遗憾,它们没有帮助我。

  4. 我以Post作为父实体,Comment作为子实体。一个帖子可以有很多评论。代码:

如果我在Comment中使用它:

@ManyToOne(fetch = FetchType.LAZY)   
@JoinColumn(name = "post_id")  
private Post post;  

这在Post中:

private Set<Comment> comments; 

因此,我删除了@OneToMany,如上述教程所述,我得到了:

MappingException: Could not determine type for: java.util.List, at table: post, for columns: [org.hibernate.mapping.Column(comments)]

那么,如何使用“ @ManyToOne”关联(或其他方便的方式)来控制comments的大小和分页?

2 个答案:

答案 0 :(得分:1)

您可以通过使用JpaRepository中的Spring data来避免使用EntityManager。 JpaRepository带有内置方法Page<T> findAll(Pageable pageable),可用于分页。您可以阅读本文以开始使用:https://www.baeldung.com/spring-data-repositories

祝你好运!

编辑:另外,关于第4点:

@ManyToOne(fetch = FetchType.LAZY)   
@JoinColumn(name = "post_id")  
private Post post; 

您在这里基本上是在说评论可以有很多帖子,而不是相反(帖子可以有很多评论)。另外,如果不同时使用OneToMany,就无法使用ManyToOne。

答案 1 :(得分:0)

我发现并不完美,但对我来说是最正确的解决方案。

帖子:

@Entity(name = "Post")
public class Post {

    //...
    @Transient
    private List<PostComment> comments;

    public void addComment(PostComment comment) {
        comments.add(comment);
        comment.setPost(this);
    }

    public void removeComment(PostComment comment) {
        comments.remove(comment);
        comment.setPost(null);
    }

    public void clearComments(){
        comments.clear();
    }

    public List<PostComment> getComments() {
        return comments;
    }

    public void setComments(List<PostComment> comments) {
        this.comments = comments;
    }
}

后期评论:

@Entity(name = "PostComment")
public class PostComment {

    //...

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "post_id")
    private Post post;

    public Post getPost() {
        return post;
    }

    public void setPost(Post post) {
        this.post = post;
    }
}

PostCommentServiceImpl:

@Service
public class PostCommentServiceImpl {

    @Autowired
    private PostCommentRepository repository;

    //...

    public void setCommentsInPost(Post post, int first, int size){
        Pageable pageRequest = new PageRequest(first, size);

        Page<PostComment> pageOfPostComment = repository.findByPostId(post.getId(), pageRequest);

        post.setComments(pageOfPostComment.getContent());
    }
}

控制器:

@Controller
public class PostController {
    @Autowired
    private PostCommentService postCommentService;

    @Autowired
    private PostService postService;

    //...
    @RequestMapping(value = "/something", method = RequestMethod.GET)
    public void foo() {
        Post post = postService.findById(1L);

        postCommentService.setCommentsInPost(post,0,10);

        //...
    }
    //...
}