views:

34

answers:

1

I have one Entity call Comment

Comment
+ id (PK)
+ fromUserId
+ targetId
+ replyId : This is the foreign key to id

The idea is a comment can have many replies, but a reply is also a comment. To distinguish between the two, a comment will have replyId equal -1, meanwhile a reply will have a non -1 value for replyId. Ultimately, what I want is for Comment to have a List like this

List<Comment> replyList;  //So each comment will store all their replies into this List

In JPA, I accomplish OneToMany relationship between two Entity, I create a List with the help of @OneToMany and @ManyToOne annotation, but in this case I am not sure how to accomplish this. Please help

EDIT
They way I create a Comment - Reply layout is by having one dataTable inside another

<h:form id="table">
<p:dataTable value="#{bean.comments}" var="item">
    <!-- Original Comment -->
    <p:column>
        <h:outputText value="#{item.comment}" />
    </p:column>

    <!-- Reply -->
    <p:column>
        <p:dataTable value="#{item.replies}" rendered="#{item.replies.size() > 0}" var="item2">
             <!-- Print out replies in here -->
             <h:outputText value="#{item2.comment}" />
        </p:dataTable>

        <!-- Text box and commandButton so user can add new reply -->
        <h:inputTextarea value="#{...}" />
        <p:commandButton value="Post" actionListener="#{bean.addReply(item)}" />
        <!-- Assume that I got this working, that a new Comment with correct REPLYTO_ID set -->
    </p:column>
</p:dataTable>
</h:form>

Here is my problem. When I type a reply and click Post, it creates an item entry in my database correctly, and after that recall getReplies(). I was assume at this point, replies.size() == 1, however replies.size() is equals to 0. Therefore I see nothing. I have to refresh the page, to see it display correct. I kind of see the problem here, since I generated the value of the second table by #{item.replies}, therefore if item is not update to date, then replies is not update to date. Not sure if this is JSF or JPA problem

+1  A: 

You can map a self referencing entity like this:

@Entity
public class Comment {
    @Id
    private Long id;

    @ManyToOne(optional=true, fetch=FetchType.LAZY)
    @JoinColumn(name="REPLYTO_ID")
    private Comment replyTo;

    @OneToMany(mappedBy="replyTo")
    private List<Comment> replies = new ArrayList<Comment>();

    //...

    // link management method
    public void addToComments(Comment comment) {
        this.comments.add(comment);
        comment.setParent(parent);
    }
}

Where the root Comment has no replyTo.

PS: make sure to set the bi-directional association correctly.

Pascal Thivent
In the JPQL, if u want to look for only the root `Comment`, you say something like this: `SELECT c from COMMENT c WHERE c.replyTo IS NULL`. Is that right?
Harry Pham
@Harry Yes, that's what I meant by "no replyTo", the root comment doesn't have any replyTo so it's null.
Pascal Thivent
Thank you, I got that part working. However I kind of ran into another issue related to the one you just answer. I wrote some code, would u please take a look at my post, the EDIT part. I can post this as a separate question if u want me to, but I just dont know what to put for the title.
Harry Pham
@Harry Just to be sure, do you set both sides of the association correctly?
Pascal Thivent
yeah. I actually figure out what wrong. Just like I said, `since I generated the value of the second table by #{item.replies}, therefore if item is not update to date, then replies is not update to date.` So in the method that I post a reply, I update the list of the original comments. That fixes it. Thank you for all your help. :D
Harry Pham