I've concerns about the code below because I'm getting a lot of unnecessary data from my DB and I delete it afterward to only have the "good" data. I didn't find any good workaround to get the data directly from the query.
Basically what I have is like the Reddit comment section. There are comments (post entity) which have votes on them (postvotes entity). What I'm interested in having is the votes from the current user watching the thread so I can decide if they already upvoted or downvoted a post.
This is my original query that returns what I want:
private static final String FIND_POSTS_BY_THREAD_ID_WITH_VOTES = "SELECT p FROM Post p LEFT JOIN FETCH p.postVotes pv ON pv.user1=:currentUser WHERE p.thethread.idthread=:id AND p.replyTo IS NULL";
This query takes the posts (comments) that have a replyTo
column to null. That means that those comments are not a reply to another comment. With this query I also have only the votes from the current user. Which is good. I have post in a thread which are not a reply to another comment, then I can use getReplies()
from my Post
entity to have the replies. However those replies will contain the wrong list of PostVotes
. If you don't understand why I'm returning the comments that have a column replyTo
null check the Reddit comment section, those posts (comments) are the ones on the outer left of each block.
Post
Entity - Scroll down to see the function that I'm currently using to get the correct PostVotes
:
@Entity
@Table(name = "posts")
@NamedQuery(name = "Post.findAll", query = "SELECT p FROM Post p")
public class Post implements Serializable, Comparable<Post> {
private static final long serialVersionUID = 1L;
@Id
private int idpost;
private String content;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "date_post")
private Date datePost;
private int downvotes;
private int upvotes;
// bi-directional many-to-one association to PostVote
@OneToMany(mappedBy = "post")
private List<PostVote> postVotes;
// bi-directional many-to-one association to Post
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "reply_to_post")
private Post replyTo;
// bi-directional many-to-one association to Post
@OneToMany(mappedBy = "replyTo")
private List<Post> replies;
// bi-directional many-to-one association to Thethread
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "threads_idthread")
private Thethread thethread;
// bi-directional many-to-one association to User
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "users_username")
private User user;
// -------------------- I don't like having to use this -----------------
// ----------------------------------------------------------------
public List<PostVote> getPostVote4User(User user) {
this.getPostVotes().removeIf(
v -> !v.getUser1().getUsername().equals(user.getUsername()));
return this.getPostVotes();
}
}
The method getPostVote4User()
exists because I'm only Interested in the votes by the user watching the page! I said earlier that my query returns exactly that so why is this method needed? Yes my original query returns what I need, which is a list of 0
or 1
elements by the user when calling getPostVotes()
. However if I access a votes from a post like this:
post.getReplies.get(0).getPostVotes()
The list will contain the votes from every user.
PostVote
entity
@Entity
@Table(name = "post_votes")
@NamedQuery(name = "PostVote.findAll", query = "SELECT p FROM PostVote p")
public class PostVote implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "idpost_votes")
private int idpostVotes;
private int vote;
// bi-directional many-to-one association to Post
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "posts_idpost")
private Post post;
// bi-directional many-to-one association to User
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "from_user")
private User user1;
// bi-directional many-to-one association to User
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "to_user")
private User user2;
}