package com.kyamran.app.controller;

import com.kyamran.app.model.Label;
import com.kyamran.app.model.Post;
import com.kyamran.app.service.LabelService;

import java.util.List;


public class LabelController {
    LabelService labelService = new LabelService();

    public Label save(Label label) {
        return labelService.save(label);
    }

    public Label update(Label label) {
        return labelService.update(label);
    }

    public Label getById(Long Long) {
        return labelService.getById(Long);
    }

    public void deleteById(Long Long) {
        labelService.deleteById(Long);
    }

    public List<Label> getAll() {
        return labelService.getAll();
    }
    public void savePostLabels(Post post, List<Label> labels) {
        labelService.savePostLabels(post, labels);
    }

}

package com.kyamran.app.controller;

import com.kyamran.app.model.Post;
import com.kyamran.app.service.PostService;

import java.util.List;

public class PostController {
    PostService postService = new PostService();

    public Post save(Post type) {
        return postService.save(type);
    }

    public Post update(Post type) {
        return postService.update(type);
    }

    public Post getById(Long aLong) {
        return postService.getById(aLong);
    }

    public void deleteById(Long aLong) {
        postService.deleteById(aLong);
    }

    public List<Post> getAll() {
        return postService.getAll();
    }

}

package com.kyamran.app.model;

import lombok.Builder;
import lombok.Getter;

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

@Getter
@Entity
@Table(name = "labels")
public class Label {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Column(name = "name")
    private String name;

    @ManyToMany(mappedBy = "labels",
            cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH},
            fetch = FetchType.LAZY)


    private List<Post> posts;

    public Label() {
    }

      public Label(Long id) {
          this.id = id;
      }
    @Builder
    public Label(Long id, String name) {
        this.id = id;
        this.name = name;
    }


    public Label(String name) {
        this.name = name;
    }

    public void setId(Long id) {
        this.id = id;
    }

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

    public void setPosts(List<Post> posts) {
        this.posts = posts;
    }

    @Override
    public String toString() {
        return "Label{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}




package com.kyamran.app.model;

import lombok.Getter;

import javax.persistence.*;
import java.time.LocalDate;
import java.util.List;

@Entity
@Table(name = "posts")
public class Post {
    @Getter
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Getter
    @Column(name = "content")
    private String content;

    @Getter
    @Column(name = "created")
    private LocalDate created;

    @Getter
    @Column(name = "updated")
    private LocalDate updated;

    @Getter
    @Column(name = "postStatus")
    @Enumerated(EnumType.STRING)
    private PostStatus postStatus;

    @ManyToMany(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH},
            fetch = FetchType.LAZY)
    @JoinTable(
            name = "post_labels",
            joinColumns = {@JoinColumn(name = "PostID")},
            inverseJoinColumns = {@JoinColumn(name = "LabelID")}
    )
    private List<Label> labels;

    @Getter
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "WriterID", nullable = false)
    private Writer writer;

    public Post(List<Label> labels) {
        this.labels = labels;
    }

    public Post(String content, List<Label> labels, Writer writer) {
        this.content = content;
        this.labels = labels;
        this.writer = writer;
    }

    public Post() {

    }

    public void setId(Long id) {
        this.id = id;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public void setCreated(String created) {
        this.created = LocalDate.parse(created);
    }

    public void setUpdated(String updated) {
        this.updated = LocalDate.parse(updated);
    }

    public void setPostStatus(PostStatus postStatus) {
        this.postStatus = postStatus;
    }

    public void setWriter(Writer writer) {
        this.writer = writer;
    }


    @Override
    public String toString() {
        return "Post{" +
                "id=" + id +
                ", content='" + content + '\'' +
                ", created=" + created +
                ", updated=" + updated +
                ", postStatus=" + postStatus +
                ", labels=" + labels +
                ", writer=" + writer.getId() +
                '}';
    }

    /*public void setLabels(List<Label> labels) {
        this.labels = labels;
    }*/
}

package com.kyamran.app.repository.hibernateImpl;

import com.kyamran.app.model.Label;
import com.kyamran.app.model.Post;
import com.kyamran.app.repository.LabelRepository;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import java.util.ArrayList;
import java.util.List;

public class LabelRepositoryImpl implements LabelRepository {
    private static LabelRepositoryImpl instance;
    private static final SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();

    private LabelRepositoryImpl() {
    }

    public static LabelRepositoryImpl getInstance() {
        if (instance == null) {
            instance = new LabelRepositoryImpl();
        }
        return instance;
    }

    @Override
    public Label save(Label label) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();

        session.save(label);

        transaction.commit();
        session.close();

        return label;
    }

    @Override
    public Label update(Label label) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();

        session.update(label);

        transaction.commit();
        session.close();

        return label;
    }

    @Override
    public Label getById(Long id) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();

        Label label = session.get(Label.class, id);

        transaction.commit();
        session.close();

        return label;
    }

    @Override
    public void deleteById(Long id) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();

        Label label = session.get(Label.class, id);
        if (label != null) {
            session.delete(label);
        }

        transaction.commit();
        session.close();
    }

    @Override
    public List<Label> getAll() {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();

        List<Label> labels = session.createQuery("FROM Label", Label.class).list();

        transaction.commit();
        session.close();

        return labels;
    }
    @Override
    public void savePostLabels(Post post, List<Label> labels) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();

        for (Label label : labels) {
            if (label.getPosts() == null) {
                label.setPosts(new ArrayList<>()); 
            }
            label.getPosts().add(post);
            session.saveOrUpdate(label);
        }

        transaction.commit();
        session.close();
    }
}

package com.kyamran.app.repository.hibernateImpl;

import com.kyamran.app.model.Post;
import com.kyamran.app.model.PostStatus;
import com.kyamran.app.model.Writer;
import com.kyamran.app.repository.PostRepository;
import com.kyamran.app.utilities.DateFormatter;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import java.util.List;

public class PostRepositoryImpl implements PostRepository {
    private static PostRepositoryImpl instance;
    private static final SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();

    private PostRepositoryImpl() {
    }

    public static PostRepositoryImpl getInstance() {
        if (instance == null) {
            instance = new PostRepositoryImpl();
        }
        return instance;
    }

    @Override
    public Post save(Post post) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();

        post.setPostStatus(PostStatus.ACTIVE);
        post.setUpdated(DateFormatter.getCurrentDate());
        post.setCreated(DateFormatter.getCurrentDate());

        Writer writer = post.getWriter();
        if (writer != null && writer.getId() == null) {
            session.save(writer);
        }

        session.save(post);
        transaction.commit();
        session.close();

        return post;
    }

    @Override
    public Post update(Post post) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();

        post.setPostStatus(PostStatus.UNDER_REVIEW);
        session.update(post);

        transaction.commit();
        session.close();

        return post;
    }

    @Override
    public Post getById(Long id) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();

        Post post = session.get(Post.class, id);

        transaction.commit();
        session.close();

        return post;
    }

    @Override
    public void deleteById(Long id) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();

        Post post = session.get(Post.class, id);
        if (post != null) {
            post.setPostStatus(PostStatus.DELETED);
            session.update(post);
        }

        transaction.commit();
        session.close();
    }

    @Override
    public List<Post> getAll() {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();

        List<Post> posts = session.createQuery("FROM Post", Post.class).list();

        transaction.commit();
        session.close();

        return posts;
    }

    @Override
    public List<Post> returnPostsByWriterId(Long id) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();

        List<Post> posts = session.createQuery("FROM Post WHERE Writer = :id", Post.class)
                .setParameter("id", id)
                .list();

        transaction.commit();
        session.close();

        return posts;
    }
}

package com.kyamran.app.service;

import com.kyamran.app.model.Label;
import com.kyamran.app.model.Post;
import com.kyamran.app.repository.LabelRepository;
import com.kyamran.app.repository.hibernateImpl.LabelRepositoryImpl;

import java.util.List;

public class LabelService {
    LabelRepository labelRepository = LabelRepositoryImpl.getInstance();

    public void setLabelRepository(LabelRepository labelRepository) {
        this.labelRepository = labelRepository;
    }

    public Label save(Label label) { return labelRepository.save(label); }


    public Label update(Label label) {
        return labelRepository.update(label);
    }


    public Label getById(Long Long) {
        return labelRepository.getById(Long);
    }


    public void deleteById(Long Long) {
        labelRepository.deleteById(Long);
    }


    public List<Label> getAll() {
        return labelRepository.getAll();
    }

    public void savePostLabels(Post post, List<Label> labels) {
        labelRepository.savePostLabels(post, labels);
    }
}

package com.kyamran.app.service;

import com.kyamran.app.model.Post;
import com.kyamran.app.repository.PostRepository;
import com.kyamran.app.repository.hibernateImpl.PostRepositoryImpl;
import com.kyamran.app.model.Label;
import java.util.List;

public class PostService {
    PostRepository postRepository = PostRepositoryImpl.getInstance();

    public void setPostRepository(PostRepository postRepository) {
        this.postRepository = postRepository;
    }

    public Post save(Post post) { return postRepository.save(post); }

    public Post update(Post post) {
        return postRepository.update(post);
    }

    public Post getById(Long Long) {
        return postRepository.getById(Long);
    }

    public void deleteById(Long Long) {
        postRepository.deleteById(Long);
    }

    public List<Post> getAll() {
        return postRepository.getAll();
    }

}


package com.kyamran.app.view;

import com.kyamran.app.controller.LabelController;
import com.kyamran.app.controller.PostController;
import com.kyamran.app.model.Label;
import com.kyamran.app.model.Post;

import java.util.Collections;
import java.util.InputMismatchException;
import java.util.List;
import java.util.Scanner;

public class LabelView implements View {
    private static final String OPERATIONS_INFO = """
                ----------------------------------
                1: Save label.
                2: Update label.
                3: Get label by ID.
                4: Delete label.
                5: Get all labels.
                6: Exit.
                ----------------------------------
                """;

    private final Scanner in = new Scanner(System.in);
    private final LabelController labelController = new LabelController();

    private final PostController postController = new PostController();
    @Override
    public void run() {
        try {
            boolean appStatus = true;
            while (appStatus) {
                System.out.println(OPERATIONS_INFO);
                System.out.print("Enter a command: ");
                String operation = in.next();

                switch (operation) {
                    case "1" -> saveLabelView();
                    case "2" -> updateLabelView();
                    case "3" -> getByIdLabelView();
                    case "4" -> deleteByIdLabelView();
                    case "5" -> getAllLabelView();
                    case "6" -> appStatus = false;
                    default -> System.out.println("Incorrect, try again.");
                }
            }
        } catch (InputMismatchException e) {
            System.out.println("Input error.");
        }
    }

    private void saveLabelView() {
        System.out.println("Input name: ");
        String name = in.next();
        System.out.println("Input post ID: ");
        Long postId = in.nextLong();
        Label label = new Label();
        label.setName(name);

        label = labelController.save(label);
        System.out.println("Added: " + label);

        Post post = postController.getById(postId);
        labelController.savePostLabels(post, Collections.singletonList(label));
    }


    private void updateLabelView() {
        System.out.println("Select label ID: ");
        Long id = in.nextLong();
        System.out.println("Select new Name: ");
        String name = in.next();

        Label label = labelController.update(Label.builder()
                .id(id)
                .name(name)
                .build());
        System.out.println("Updated label: " + label);
    }

    private void getAllLabelView() {
        List<Label> labelList = labelController.getAll();
        labelList.forEach(System.out::println);
    }

    private void deleteByIdLabelView() {
        System.out.println("Input label ID: ");
        Long id = in.nextLong();

        labelController.deleteById(id);
        System.out.println("Success delete!");
    }

    private void getByIdLabelView() {
        System.out.println("Input label ID: ");
        Long id = in.nextLong();

        Label label = labelController.getById(id);
        if (label == null) {
            System.out.println("ID not found, try again");
        } else {
            System.out.println(label);
        }
    }
}

package com.kyamran.app.view;

import com.kyamran.app.controller.PostController;
import com.kyamran.app.model.Post;
import com.kyamran.app.model.Writer;
import com.kyamran.app.service.WriterService;

import java.util.InputMismatchException;
import java.util.List;
import java.util.Scanner;

public class PostView implements View {
    private static final String OPERATIONS_INFO = """
            ----------------------------------
            1: Save post.
            2: Update post.
            3: Get post by ID.
            4: Delete post.
            5: Get all posts.
            6: Exit.
            ----------------------------------
            """;

    private final Scanner in = new Scanner(System.in);
    private final PostController postController = new PostController();
    private final WriterService writerService = new WriterService();

    @Override
    public void run() {
        try {
            boolean appStatus = true;
            while (appStatus) {
                System.out.println(OPERATIONS_INFO);
                System.out.print("Enter a command: ");
                String operation = in.next();

                switch (operation) {
                    case "1" -> savePostView();
                    case "2" -> updatePostView();
                    case "3" -> getPostByIdView();
                    case "4" -> deletePostByIdView();
                    case "5" -> getAllPostView();
                    case "6" -> appStatus = false;
                    default -> System.out.println("Incorrect, try again.");
                }
            }
        } catch (InputMismatchException e) {
            System.out.println("Input error.");
        }
    }

    public void savePostView() {
        in.nextLine();
        System.out.print("Input content: ");
        String content = in.nextLine();
        System.out.print("Input writer ID: ");
        Long writerId = null;
        if (in.hasNextLong()) {
            writerId = in.nextLong();
        } else {
            System.out.println("You should enter a valid Writer ID.");
        }
        if (writerId != null) {
            Writer writer = writerService.getById(writerId);
            Post newPost = new Post();
            newPost.setContent(content);
            newPost.setWriter(writer);
            postController.save(newPost);
            System.out.println("Saved!");
        }
    }

    public void updatePostView() {
        System.out.print("Input post ID: ");
        Long id = in.nextLong();
        in.nextLine();
        Post postToUpdate = postController.getById(id);
        if (postToUpdate == null) {
            System.out.println("Post not found!");
            return;
        }

        System.out.print("Input new content: ");
        String content = in.nextLine();
        postToUpdate.setContent(content);
        Post updatedPost = postController.update(postToUpdate);
        System.out.println("Updated post: ");
        System.out.println(updatedPost);
    }



    public void getPostByIdView() {
        System.out.print("Input post ID: ");
        Long id = in.nextLong();
        Post post = postController.getById(id);
        System.out.println(post);
    }

    public void deletePostByIdView() {
        System.out.print("Input post ID: ");
        Long id = in.nextLong();
        postController.deleteById(id);
        System.out.println("Deleted!");
    }

    public void getAllPostView() {
        List<Post> postList = postController.getAll();
        postList.forEach(System.out::println);
    }
}

CREATE TABLE IF NOT EXISTS Labels (
    ID SERIAL PRIMARY KEY,
    Name VARCHAR(32) NOT NULL
);

CREATE TABLE Writers (
    ID BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY,
    FirstName VARCHAR(255) NOT NULL,
    LastName VARCHAR(255) NOT NULL,
    PRIMARY KEY(ID)
);

CREATE TABLE Posts (
    ID BIGSERIAL,
    Content VARCHAR(255) NOT NULL,
    Created DATE NOT NULL,
    Updated DATE NOT NULL,
    PostStatus VARCHAR(255) NOT NULL,
    WriterId BIGINT,
    PRIMARY KEY(ID),
    FOREIGN KEY (WriterId) REFERENCES Writers(ID)
);

CREATE TABLE IF NOT EXISTS Post_Labels (
    PostID BIGINT NOT NULL,
    LabelID INT NOT NULL,
    FOREIGN KEY (PostID) REFERENCES Posts(ID),
    FOREIGN KEY (LabelID) REFERENCES Labels(ID),
    UNIQUE (PostID, LabelID)
);        не заполняются таблица  Post_Labels! Остается пустой. Что делать? Как решить ?