0

I want to avoid "Bidirectional @OneToMany" association due to:

  1. It cannot limit the size of a @OneToMany
  2. I need to do pagination.

For this I used this tutorial which described "Just @ManyToOne" association, but, unfortunately, it gives only one line of code related to this:

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

So, I have many questions:

  1. Where exactly should I use this line?

  2. How and where should I obtain EntityManager? Exactly in the entity? Is it a good solution?

  3. How can I avoid using EntityManager? I already looked at this and other questions, but unfortunately they didn't help me.

  4. I have Post as a parent and Comment as a child entity. One post can has many comments. Code:

If I use this in the Comment:

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

And this in the Post:

private Set<Comment> comments; 

So, I deleted @OneToMany as above-mentioned tutorial said, I got:

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

So, how can I use "Just @ManyToOne" association(or something else convenient) to get control of the size and pagination for comments?

konstantin_doncov
  • 2,725
  • 4
  • 40
  • 100
  • This is way too broad. You need to understand what you want to do first, then read the Spring and the Spring-data-jpa documentation, learn JPA, JPQL, look at spring-data-jpa examples and tutorials, etc. – JB Nizet Aug 12 '18 at 15:49

2 Answers2

1

you can avoid using EntityManager by using the JpaRepository of Spring data instead. The JpaRepository comes with the built-in method Page<T> findAll(Pageable pageable) that you can use for pagination. You can read this article to get you started: https://www.baeldung.com/spring-data-repositories

Good luck!

Maurice
  • 6,698
  • 9
  • 47
  • 104
  • Thanks for your answer! Ooops, very stupid mistake in the 4 point. And I have two questions about associations: **1.** You said that "you can't use ManyToOne without using OneToMany as well", but what about "Just @ManyToOne" point in [this tutorial](https://vladmihalcea.com/the-best-way-to-map-a-onetomany-association-with-jpa-and-hibernate/)? **2.** Also, you suggested to use `ManyToOne` and `OneToMany`, but mentioned tutorial said that "you cannot limit the size of a @OneToMany collection", so in which way I can use your suggestion? – konstantin_doncov Aug 12 '18 at 21:21
  • you should ask the author of the article what he means with `the @ManyToOne annotation on the child side is everything you need.`. To my knowledge you can't use @ManyToOne without @OneToMany. You can however use @OneToMany without @ManyToOne. Then its a unidirectional relationship – Maurice Aug 14 '18 at 15:05
  • by the way, could you accept the answer if it answers you question? – Maurice Aug 14 '18 at 15:17
  • Sorry! I totally forgot about this post. After that I found some solution, you can check it. Anyway, thanks! – konstantin_doncov Oct 09 '18 at 03:58
1

I found not perfect, but the most correct solution for me.

Post:

@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;
    }
}

PostComment:

@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:

@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);

        //...
    }
    //...
}
konstantin_doncov
  • 2,725
  • 4
  • 40
  • 100