diff --git a/logs/app.log b/logs/app.log new file mode 100644 index 000000000..e69de29bb diff --git a/pom.xml b/pom.xml index 774bb70e9..637a16285 100644 --- a/pom.xml +++ b/pom.xml @@ -18,6 +18,12 @@ + + org.apache.logging.log4j + log4j-core + 2.23.1 + + junit junit diff --git a/src/main/java/core/basesyntax/Main.java b/src/main/java/core/basesyntax/Main.java new file mode 100644 index 000000000..f1fec19ae --- /dev/null +++ b/src/main/java/core/basesyntax/Main.java @@ -0,0 +1,55 @@ +package core.basesyntax; + +import core.basesyntax.dao.MessageDao; +import core.basesyntax.dao.UserDao; +import core.basesyntax.dao.impl.MessageDaoImpl; +import core.basesyntax.dao.impl.SmileDaoImpl; +import core.basesyntax.dao.impl.UserDaoImpl; +import core.basesyntax.model.Comment; +import core.basesyntax.model.Message; +import core.basesyntax.model.MessageDetails; +import core.basesyntax.model.Smile; +import core.basesyntax.model.User; +import java.time.LocalDateTime; +import java.util.List; +import org.hibernate.SessionFactory; + +public class Main { + public static void main(String[] args) { + SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + SmileDaoImpl smileDao = new SmileDaoImpl(sessionFactory); + + Smile smile = new Smile(); + smile.setValue("happy :)"); + Comment comment = new Comment(); + comment.setContent("This is a comment!"); + List smiles = List.of(smile); + for (Smile oneSmile : smiles) { + oneSmile.setComment(comment); + } + comment.setSmiles(smiles); + + UserDao userDao = new UserDaoImpl(sessionFactory); + User user = new User(); + user.setUsername("John"); + user.setComments(List.of(comment)); + userDao.create(user); + + MessageDetails messageDetails = new MessageDetails(); + messageDetails.setSender(user.getUsername()); + messageDetails.setSentTime(LocalDateTime.now()); + + MessageDao messageDao = new MessageDaoImpl(sessionFactory); + Message message = new Message(); + message.setContent("Stay calm!"); + message.setMessageDetails(messageDetails); + List allMessages = messageDao.getAll(); + for (Message text : allMessages) { + System.out.println(text); + } + messageDao.create(message); + + User userFromDb = userDao.get(5L); + userDao.remove(userFromDb); + } +} diff --git a/src/main/java/core/basesyntax/dao/UserDao.java b/src/main/java/core/basesyntax/dao/UserDao.java index 0c66364d5..bad4cdee0 100644 --- a/src/main/java/core/basesyntax/dao/UserDao.java +++ b/src/main/java/core/basesyntax/dao/UserDao.java @@ -3,5 +3,4 @@ import core.basesyntax.model.User; public interface UserDao extends GenericDao { - } diff --git a/src/main/java/core/basesyntax/dao/impl/CommentDaoImpl.java b/src/main/java/core/basesyntax/dao/impl/CommentDaoImpl.java index 5176c951f..c92cf51e8 100644 --- a/src/main/java/core/basesyntax/dao/impl/CommentDaoImpl.java +++ b/src/main/java/core/basesyntax/dao/impl/CommentDaoImpl.java @@ -2,31 +2,93 @@ import core.basesyntax.dao.CommentDao; import core.basesyntax.model.Comment; +import core.basesyntax.model.Smile; +import java.util.ArrayList; import java.util.List; +import org.hibernate.Session; import org.hibernate.SessionFactory; +import org.hibernate.Transaction; public class CommentDaoImpl extends AbstractDao implements CommentDao { + private final SmileDaoImpl smileDao = new SmileDaoImpl( + factory.openSession().getSessionFactory()); + public CommentDaoImpl(SessionFactory sessionFactory) { super(sessionFactory); } @Override - public Comment create(Comment entity) { - return null; + public Comment create(Comment comment) { + Session session = null; + Transaction transaction = null; + try { + session = factory.openSession(); + transaction = session.beginTransaction(); + + List smiles = new ArrayList<>(); + for (Smile smile : comment.getSmiles()) { + Smile smileInDb = smileDao.get(smile.getId()); + if (smileInDb == null) { + throw new RuntimeException("Smile entity does not exist in the database"); + } else { + Smile managedSmile = (Smile) session.merge(smileInDb); + smiles.add(managedSmile); + } + } + comment.setSmiles(smiles); + session.persist(comment); + + transaction.commit(); + return comment; + } catch (Exception e) { + if (transaction != null) { + transaction.rollback(); + } + throw new RuntimeException("Can't insert Comment ", e); + } finally { + if (session != null) { + session.close(); + } + } } @Override public Comment get(Long id) { - return null; + try (Session session = factory.openSession()) { + return session.get(Comment.class, id); + } catch (Exception e) { + throw new RuntimeException("Can't get Comment by id: " + id, e); + } } @Override public List getAll() { - return null; + String query = "SELECT * FROM comments"; + try (Session session = factory.openSession()) { + return session.createNativeQuery(query, Comment.class).getResultList(); + } catch (Exception e) { + throw new RuntimeException("Can't get all Comment ", e); + } } @Override - public void remove(Comment entity) { - + public void remove(Comment comment) { + Session session = null; + Transaction transaction = null; + try { + session = factory.openSession(); + transaction = session.beginTransaction(); + session.remove(comment); + transaction.commit(); + } catch (Exception e) { + if (transaction != null) { + transaction.rollback(); + } + throw new RuntimeException("Can't delete Comment ", e); + } finally { + if (session != null) { + session.close(); + } + } } } diff --git a/src/main/java/core/basesyntax/dao/impl/MessageDaoImpl.java b/src/main/java/core/basesyntax/dao/impl/MessageDaoImpl.java index 9b899fa95..3c6ad1873 100644 --- a/src/main/java/core/basesyntax/dao/impl/MessageDaoImpl.java +++ b/src/main/java/core/basesyntax/dao/impl/MessageDaoImpl.java @@ -3,7 +3,9 @@ import core.basesyntax.dao.MessageDao; import core.basesyntax.model.Message; import java.util.List; +import org.hibernate.Session; import org.hibernate.SessionFactory; +import org.hibernate.Transaction; public class MessageDaoImpl extends AbstractDao implements MessageDao { public MessageDaoImpl(SessionFactory sessionFactory) { @@ -12,21 +14,63 @@ public MessageDaoImpl(SessionFactory sessionFactory) { @Override public Message create(Message entity) { - return null; + Session session = null; + Transaction transaction = null; + try { + session = factory.openSession(); + transaction = session.beginTransaction(); + session.persist(entity); + transaction.commit(); + return entity; + } catch (Exception e) { + if (transaction != null) { + transaction.rollback(); + } + throw new RuntimeException("Can't insert Message entity", e); + } finally { + if (session != null) { + session.close(); + } + } } @Override public Message get(Long id) { - return null; + try (Session session = factory.openSession()) { + return session.get(Message.class, id); + } catch (Exception e) { + throw new RuntimeException("Can't get Message entity by id: " + id, e); + } } @Override public List getAll() { - return null; + String query = "SELECT * FROM messages"; + try (Session session = factory.openSession()) { + return session.createNativeQuery(query, Message.class).getResultList(); + } catch (Exception e) { + throw new RuntimeException("Can't get all Message entities", e); + } } @Override public void remove(Message entity) { - + Session session = null; + Transaction transaction = null; + try { + session = factory.openSession(); + transaction = session.beginTransaction(); + session.delete(entity); + transaction.commit(); + } catch (Exception e) { + if (transaction != null) { + transaction.rollback(); + } + throw new RuntimeException("Can't delete Message entity", e); + } finally { + if (session != null) { + session.close(); + } + } } } diff --git a/src/main/java/core/basesyntax/dao/impl/MessageDetailsDaoImpl.java b/src/main/java/core/basesyntax/dao/impl/MessageDetailsDaoImpl.java index fb96d35aa..7ff593ed6 100644 --- a/src/main/java/core/basesyntax/dao/impl/MessageDetailsDaoImpl.java +++ b/src/main/java/core/basesyntax/dao/impl/MessageDetailsDaoImpl.java @@ -2,7 +2,9 @@ import core.basesyntax.dao.MessageDetailsDao; import core.basesyntax.model.MessageDetails; +import org.hibernate.Session; import org.hibernate.SessionFactory; +import org.hibernate.Transaction; public class MessageDetailsDaoImpl extends AbstractDao implements MessageDetailsDao { public MessageDetailsDaoImpl(SessionFactory sessionFactory) { @@ -11,11 +13,32 @@ public MessageDetailsDaoImpl(SessionFactory sessionFactory) { @Override public MessageDetails create(MessageDetails entity) { - return null; + Session session = null; + Transaction transaction = null; + try { + session = factory.openSession(); + transaction = session.beginTransaction(); + session.persist(entity); + transaction.commit(); + return entity; + } catch (Exception e) { + if (transaction != null) { + transaction.rollback(); + } + throw new RuntimeException("Can't insert MessageDetails entity", e); + } finally { + if (session != null) { + session.close(); + } + } } @Override public MessageDetails get(Long id) { - return null; + try (Session session = factory.openSession()) { + return session.get(MessageDetails.class, id); + } catch (Exception e) { + throw new RuntimeException("Can't get MessageDetails entity by id: " + id, e); + } } } diff --git a/src/main/java/core/basesyntax/dao/impl/SmileDaoImpl.java b/src/main/java/core/basesyntax/dao/impl/SmileDaoImpl.java index 559248cda..542dd5cd1 100644 --- a/src/main/java/core/basesyntax/dao/impl/SmileDaoImpl.java +++ b/src/main/java/core/basesyntax/dao/impl/SmileDaoImpl.java @@ -3,7 +3,9 @@ import core.basesyntax.dao.SmileDao; import core.basesyntax.model.Smile; import java.util.List; +import org.hibernate.Session; import org.hibernate.SessionFactory; +import org.hibernate.Transaction; public class SmileDaoImpl extends AbstractDao implements SmileDao { public SmileDaoImpl(SessionFactory sessionFactory) { @@ -12,16 +14,48 @@ public SmileDaoImpl(SessionFactory sessionFactory) { @Override public Smile create(Smile entity) { - return null; + if (entity == null) { + throw new IllegalArgumentException("Entity cannot be null"); + } + Session session = null; + Transaction transaction = null; + try { + session = factory.openSession(); + transaction = session.beginTransaction(); + session.persist(entity); + transaction.commit(); + return entity; + } catch (Exception e) { + if (transaction != null) { + transaction.rollback(); + } + throw new RuntimeException("Can't insert Smile entity", e); + } finally { + if (session != null) { + session.close(); + } + } } @Override public Smile get(Long id) { - return null; + try (Session session = factory.openSession()) { + if (id == null) { + throw new IllegalArgumentException("Id cannot be null"); + } + return session.get(Smile.class, id); + } catch (Exception e) { + throw new RuntimeException("Can't get Smile entity by id: " + id, e); + } } @Override public List getAll() { - return null; + String query = "SELECT * FROM smiles"; + try (Session session = factory.openSession()) { + return session.createNativeQuery(query, Smile.class).getResultList(); + } catch (Exception e) { + throw new RuntimeException("Can't get all Smile entities", e); + } } } diff --git a/src/main/java/core/basesyntax/dao/impl/UserDaoImpl.java b/src/main/java/core/basesyntax/dao/impl/UserDaoImpl.java index 338d8248b..9e309d240 100644 --- a/src/main/java/core/basesyntax/dao/impl/UserDaoImpl.java +++ b/src/main/java/core/basesyntax/dao/impl/UserDaoImpl.java @@ -3,7 +3,10 @@ import core.basesyntax.dao.UserDao; import core.basesyntax.model.User; import java.util.List; +import org.hibernate.Hibernate; +import org.hibernate.Session; import org.hibernate.SessionFactory; +import org.hibernate.Transaction; public class UserDaoImpl extends AbstractDao implements UserDao { public UserDaoImpl(SessionFactory sessionFactory) { @@ -12,21 +15,88 @@ public UserDaoImpl(SessionFactory sessionFactory) { @Override public User create(User entity) { - return null; + Session session = null; + Transaction transaction = null; + try { + session = factory.openSession(); + transaction = session.beginTransaction(); + session.persist(entity); + transaction.commit(); + return entity; + } catch (Exception e) { + if (transaction != null) { + transaction.rollback(); + } + throw new RuntimeException("Can't insert User entity", e); + } finally { + if (session != null) { + session.close(); + } + } } @Override public User get(Long id) { - return null; + try (Session session = factory.openSession()) { + User user = session.get(User.class, id); + if (user != null) { + Hibernate.initialize(user.getComments()); + } + return user; + } catch (Exception e) { + throw new RuntimeException("Can't get User entity by id: " + id, e); + } } @Override public List getAll() { - return null; + Session session = null; + Transaction transaction = null; + try { + session = factory.openSession(); + transaction = session.beginTransaction(); + List users = session.createQuery( + "FROM User", User.class).getResultList(); + for (User user : users) { + Hibernate.initialize(user.getComments()); + } + transaction.commit(); + return users; + } catch (Exception e) { + if (transaction != null) { + transaction.rollback(); + } + throw new RuntimeException("Can't get all users.", e); + } finally { + if (session != null) { + session.close(); + } + } } @Override - public void remove(User entity) { + public void remove(User user) { + Session session = null; + Transaction transaction = null; + try { + session = factory.openSession(); + transaction = session.beginTransaction(); + if (user.getId() != null) { + session.remove(user); + } else { + throw new RuntimeException("Can't delete User without id."); + } + transaction.commit(); + } catch (Exception e) { + if (transaction != null) { + transaction.rollback(); + } + throw new RuntimeException("Can't delete User.", e); + } finally { + if (session != null) { + session.close(); + } + } } } diff --git a/src/main/java/core/basesyntax/model/Comment.java b/src/main/java/core/basesyntax/model/Comment.java index 9fba0c920..6e1a86c64 100644 --- a/src/main/java/core/basesyntax/model/Comment.java +++ b/src/main/java/core/basesyntax/model/Comment.java @@ -1,17 +1,37 @@ package core.basesyntax.model; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import java.util.ArrayList; import java.util.List; +@Entity +@Table(name = "comments") public class Comment { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String content; + @OneToMany(mappedBy = "comment", cascade = {CascadeType.PERSIST, CascadeType.MERGE}) private List smiles; + public Comment() { + } + + public Comment(String content) { + this.content = content; + } + + public Comment(String content, List smiles) { + this.content = content; + this.smiles = smiles != null ? smiles : new ArrayList<>(); + } + public Long getId() { return id; } @@ -29,10 +49,23 @@ public void setContent(String content) { } public List getSmiles() { + if (smiles == null) { + smiles = new ArrayList<>(); + } return smiles; } public void setSmiles(List smiles) { this.smiles = smiles; } + + @Override + public String toString() { + return "Comment{" + + "id=" + id + + ", content='" + content + + '\'' + + ", smiles=" + smiles + + '}'; + } } diff --git a/src/main/java/core/basesyntax/model/Message.java b/src/main/java/core/basesyntax/model/Message.java index 672b5d485..26ca9a872 100644 --- a/src/main/java/core/basesyntax/model/Message.java +++ b/src/main/java/core/basesyntax/model/Message.java @@ -1,10 +1,33 @@ package core.basesyntax.model; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; + +@Entity +@Table(name = "messages") public class Message { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String content; + @OneToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, + CascadeType.REMOVE, CascadeType.REFRESH}) + @JoinColumn(name = "message_details_id") private MessageDetails messageDetails; + public Message() { + } + + public Message(String content) { + this.content = content; + } + public Long getId() { return id; } @@ -28,4 +51,14 @@ public MessageDetails getMessageDetails() { public void setMessageDetails(MessageDetails messageDetails) { this.messageDetails = messageDetails; } + + @Override + public String toString() { + return "Message{" + + "id=" + id + + ", content='" + content + + '\'' + + ", messageDetails=" + messageDetails + + '}'; + } } diff --git a/src/main/java/core/basesyntax/model/MessageDetails.java b/src/main/java/core/basesyntax/model/MessageDetails.java index 185023dd5..43d7eefc2 100644 --- a/src/main/java/core/basesyntax/model/MessageDetails.java +++ b/src/main/java/core/basesyntax/model/MessageDetails.java @@ -1,12 +1,24 @@ package core.basesyntax.model; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; import java.time.LocalDateTime; +@Entity +@Table(name = "message_details") public class MessageDetails { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String sender; private LocalDateTime sentTime; + public MessageDetails() { + } + public Long getId() { return id; } @@ -30,4 +42,14 @@ public LocalDateTime getSentTime() { public void setSentTime(LocalDateTime sentTime) { this.sentTime = sentTime; } + + @Override + public String toString() { + return "MessageDetails{" + + "id=" + id + + ", sender='" + sender + + '\'' + + ", sentTime=" + sentTime + + '}'; + } } diff --git a/src/main/java/core/basesyntax/model/Smile.java b/src/main/java/core/basesyntax/model/Smile.java index 4395eb0f7..5e9dafc4f 100644 --- a/src/main/java/core/basesyntax/model/Smile.java +++ b/src/main/java/core/basesyntax/model/Smile.java @@ -1,17 +1,26 @@ package core.basesyntax.model; +import jakarta.persistence.CascadeType; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; @Entity +@Table(name = "smiles") public class Smile { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String value; + @ManyToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST}) + @JoinColumn(name = "comment_id") + private Comment comment; + public Smile() { } @@ -19,6 +28,14 @@ public Smile(String value) { this.value = value; } + public Comment getComment() { + return comment; + } + + public void setComment(Comment comment) { + this.comment = comment; + } + public Long getId() { return id; } @@ -38,8 +55,8 @@ public void setValue(String value) { @Override public String toString() { return "Smile{" - + "id=" + id - + ", value='" + value + '\'' - + '}'; + + "id=" + id + + ", value='" + value + '\'' + + '}'; } } diff --git a/src/main/java/core/basesyntax/model/User.java b/src/main/java/core/basesyntax/model/User.java index 0141eef00..233f0d635 100644 --- a/src/main/java/core/basesyntax/model/User.java +++ b/src/main/java/core/basesyntax/model/User.java @@ -1,12 +1,33 @@ package core.basesyntax.model; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; import java.util.List; +@Entity +@Table(name = "users") public class User { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String username; + @OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) + @JoinColumn(name = "user_id") private List comments; + public User() { + } + + public User(String username) { + this.username = username; + } + public Long getId() { return id; } @@ -30,4 +51,14 @@ public List getComments() { public void setComments(List comments) { this.comments = comments; } + + @Override + public String toString() { + return "User{" + + "id=" + id + + ", username='" + username + + '\'' + + ", comments=" + comments + + '}'; + } } diff --git a/src/main/resources/hibernate.cfg.xml b/src/main/resources/hibernate.cfg.xml index cba4560a4..b3a46f87f 100644 --- a/src/main/resources/hibernate.cfg.xml +++ b/src/main/resources/hibernate.cfg.xml @@ -5,14 +5,19 @@ - org.hibernate.dialect.MySQL8Dialect - jdbc:mysql://localhost/cinema?serverTimezone=UTC + org.hibernate.dialect.MySQLDialect + jdbc:mysql://localhost/hibernate_cascade?serverTimeZone=America/Chicago com.mysql.cj.jdbc.Driver - ma_admin - 1234 + root + kolobok0202 true update + + + + + diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml new file mode 100644 index 000000000..7f79ba76e --- /dev/null +++ b/src/main/resources/log4j2.xml @@ -0,0 +1,22 @@ + + + + + + + + + %d %p %C{1.} [%t] %m%n + + + + + + + + + + + + + diff --git a/src/test/java/core/basesyntax/dao/impl/SmileDaoImplTest.java b/src/test/java/core/basesyntax/dao/impl/SmileDaoImplTest.java index 6e69d11e5..96f7204c7 100644 --- a/src/test/java/core/basesyntax/dao/impl/SmileDaoImplTest.java +++ b/src/test/java/core/basesyntax/dao/impl/SmileDaoImplTest.java @@ -4,6 +4,7 @@ import core.basesyntax.AbstractTest; import core.basesyntax.dao.SmileDao; +import core.basesyntax.model.Comment; import core.basesyntax.model.Smile; import org.junit.Assert; import org.junit.Before; @@ -20,7 +21,8 @@ public void setUp() { @Override protected Class[] entities() { return new Class[]{ - Smile.class + Smile.class, + Comment.class }; }