package com.vladmihalcea.hibernate.masterclass.laboratory.cascade;

import com.vladmihalcea.hibernate.masterclass.laboratory.util.AbstractTest;
import org.junit.Test;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 * OneToOneCascadeTest - Test to check @OneToOne Cascading
 *
 * @author Vlad Mihalcea
 */
public class OneToManyCascadeTest extends AbstractTest {

    @Override
    protected Class<?>[] entities() {
        return new Class<?>[]{
                Post.class,
                Comment.class
        };
    }

    public Post newPost() {
        return doInTransaction(session -> {
            Post post = new Post();
            post.setName("Hibernate Master Class");

            Comment comment1 = new Comment();
            comment1.setReview("Good post!");
            Comment comment2 = new Comment();
            comment2.setReview("Nice post!");

            post.addComment(comment1);
            post.addComment(comment2);

            session.persist(post);

            return post;
        });
    }

    @Test
    public void testCascadeTypeMerge() {
        LOGGER.info("Test CascadeType.MERGE");

        Post post = newPost();
        post.setName("Hibernate Master Class Training Material");

        post.getComments()
                .stream()
                .filter(comment -> comment.getReview().toLowerCase().contains("nice"))
                .findAny()
                .ifPresent(comment -> comment.setReview("Keep on going!"));

        doInTransaction(session -> {
            session.merge(post);
        });
    }

    @Test
    public void testOrphanRemoval() {
        LOGGER.info("Test orphan removal");

        newPost();

        doInTransaction(session -> {
            Post post = (Post) session.createQuery(
                "select p " +
                "from Post p " +
                "join fetch p.comments " +
                "where p.id = :id")
            .setParameter("id", 1L)
            .uniqueResult();
            post.removeComment(post.getComments().get(0));
        });
    }

    @Test
    public void testCascadeTypeDelete() {
        LOGGER.info("Test CascadeType.DELETE");

        newPost();

        doInTransaction(session -> {
            Post post = (Post) session.get(Post.class, 1L);
            session.delete(post);
        });
    }

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

        @Id
        @GeneratedValue(strategy=GenerationType.AUTO)
        private Long id;

        private String name;

        @OneToMany(cascade = CascadeType.ALL, mappedBy = "post", orphanRemoval = true)
        private List<Comment> comments = new ArrayList<>();

        @Version
        private int version;

        public Long getId() {
            return id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

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

        public final int getVersion() {
            return version;
        }

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

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

    @Entity(name = "Comment")
    public static class Comment {

        @Id
        @GeneratedValue(strategy=GenerationType.AUTO)
        private Long id;

        @ManyToOne
        private Post post;

        private String review;

        public Long getId() {
            return id;
        }

        public Post getPost() {
            return post;
        }

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

        public String getReview() {
            return review;
        }

        public void setReview(String review) {
            this.review = review;
        }
    }

}

@@ -221,31 +221,8 @@
 st;%0A
-import java.util.Date;%0A
 impo
@@ -240,16 +240,16 @@
 l.List;%0A
+
 %0A%0A/**%0A *
@@ -1807,16 +1807,20 @@
         
+    
 %22select 
@@ -1841,16 +1841,28 @@
         
+          
+  
 %22from Po
@@ -1862,32 +1862,44 @@
 from Post p %22 +%0A
+            
                 
@@ -1941,16 +1941,28 @@
         
+            
 %22where p
@@ -1985,16 +1985,24 @@
         
+  
+      
 .setPara
@@ -2017,16 +2017,24 @@
 d%22, 1L)%0A
+        
         
@@ -2498,33 +2498,35 @@
 edValue(strategy
-=
+ = 
 GenerationType.A
@@ -2738,189 +2738,8 @@
 );%0A%0A
-        @Version%0A        private int version;%0A%0A        public Long getId() %7B%0A            return id;%0A        %7D%0A%0A        public String getName() %7B%0A            return name;%0A        %7D%0A%0A
     
@@ -2907,87 +2907,8 @@
  %7D%0A%0A
-        public final int getVersion() %7B%0A            return version;%0A        %7D%0A%0A
     
@@ -3291,17 +3291,19 @@
 strategy
-=
+ = 
 Generati
@@ -3388,16 +3388,16 @@
  post;%0A%0A
+
         
@@ -3424,140 +3424,8 @@
 w;%0A%0A
-        public Long getId() %7B%0A            return id;%0A        %7D%0A%0A        public Post getPost() %7B%0A            return post;%0A        %7D%0A%0A
     

Reduce unnecessary code