简体   繁体   中英

Making a tree of comments with Play Framework 2.3.8 with ebean ORM and java

I'm in the process of learning the Play Framework with the learn by doing approach. I'm trying to make a simple blog (using the information from the official site) and got stuck.

I'm trying to make a tree of comments of a post. So far I designed the model classes as follow:

The Post class:

@Entity
public class Post extends Model {
@Id
public Long id;

public String title;
public Date postedAt;

@Column(columnDefinition = "TEXT")
public String content;

@OneToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY, mappedBy="post")
public List<Comment> comments;

public static Finder<Long, Post> find = new Finder(Long.class, Post.class);

public static List<Post> all() {
    return find.all();
}

public static void create(Post post) {
    post.save();
}

public static void delete(Long id) {
    find.ref(id).delete();
}

}

The Comment class:

@Entity
public class Comment extends Model {
@Id
public Long id;
public String content;

public static Finder<Long, Comment> find = new Finder(Long.class, Comment.class);

public static List<Comment> all() {
    return find.all();
}

public static void create(Comment comment) {
    comment.save();
}

public static void delete(Long id) {
    find.ref(id).delete();
}

@OneToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY, mappedBy="post")
public List<ChildComment> childComments;

@ManyToOne
public Post post;

}

The ChildComment class:

public class ChildComment extends Model{
@Id
public Long id;
public String content;

@ManyToOne
public Comment comment;

}

The controller class Application.java

public class Application extends Controller {

public static Form<Post> postForm = Form.form(Post.class);

public static Result posts() {

    return ok(views.html.index.render(Post.all(), postForm));
}

public static Result index() {

    return redirect(routes.Application.posts());
}

public static Result newPost() {

    Form<Post> filledForm = postForm.bindFromRequest();
    if (filledForm.hasErrors()) {

        return badRequest(views.html.index.render(Post.all(), filledForm));
    } else {

        Post.create(filledForm.get());
        return redirect(routes.Application.posts());
    }
}

public static Result deletePost(Long id) {

    Post.delete(id);
    return redirect(routes.Application.posts());
}

}

I know I have to use one-to many relationship to achieve the task (and in the model classes I think I did it correct) but I'm got stuck of the implementation of logic in controller to manage the comments and the comments of the comments. Any clue or advise will be great.

PS I'm using a MySql database

To create a comment you can do.

Pass post id and comment data in controller

Then in Controller

//post_id and commentData received from view
Post post=Post.findByPostId(post_id);                 //find post of that comment where findByPostId() is a function in model
Comment comment=new Comment(commentData,null,post);   //Create a new Comment Object
Comment cm=Comment.save(comment);                     //where save() saves the Comment object in data base and return the saved object
List <Comments> allCommentsOnPost=post.getComments(); //get all comments on that post
allComments.add(cm);                                  //add new comment to list
post.setComments(allCommentsOnPost);                  //set the new list in Post object
post.update(post_id);                                 //update post entity

Similarly to save child comments pass comment_id,childCommentData from view

//comment_id and childCommentData received from view
Comment cm=Comment.findByCommentId(comment_id);                //find comment from id ,findByCommentId() defined in Comment entity

ChildComment childCom=new ChildComment(childCommentData,cm);    //create new object of ChildComment
ChildComment childComment=ChildComment.save(childCom);                                       //persist the child comment object in db ,save() is a function in model which saves ChildComment object and return it

List<ChildComments> allChildComments=cm.getChildComments();     //getting list of all the ChildComments .
allChildComments.add(childComment);                             //add new comment to list

cm.setChildComments(allChildComments);                          //set all the child comments in Comment Entity

cm.update(comment_id);                                          //update the Comments entity in db

Note:I am creating new Comment and ChildComment object in both the cases respectively you can also use bindRequest().get() to get the Entity object

Actually you don't need to use two classes for children - this way you have to possibility of only two levels of comment, instead just add fields to your Comment model:

@ManyToOne
public Comment parent;

@OneToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY, mappedBy="parent")
public List<Comment> children;

This way you can have theoretically unlimited branches of tree.

during creating new comment your can add ID of the parent comment - if it's null, that means that the comment is on the root level (has no parents)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM