diff --git a/pom.xml b/pom.xml index 1d545e7aa..82eb3aa40 100644 --- a/pom.xml +++ b/pom.xml @@ -15,18 +15,20 @@ https://raw.githubusercontent.com/mate-academy/style-guides/master/java/checkstyle.xml + 6.4.4.Final + 8.3.0 - org.hibernate + org.hibernate.orm hibernate-core - 6.2.7.Final + ${hibernate-core.version} - mysql - mysql-connector-java - 8.0.33 + com.mysql + mysql-connector-j + ${mysql-connector-j.version} diff --git a/src/main/java/mate/academy/Main.java b/src/main/java/mate/academy/Main.java index df492aecc..e6a967357 100644 --- a/src/main/java/mate/academy/Main.java +++ b/src/main/java/mate/academy/Main.java @@ -2,16 +2,29 @@ import java.time.LocalDate; import java.time.LocalDateTime; +import java.util.List; +import mate.academy.exception.RegistrationException; +import mate.academy.lib.Injector; import mate.academy.model.CinemaHall; import mate.academy.model.Movie; import mate.academy.model.MovieSession; +import mate.academy.model.Order; +import mate.academy.model.User; +import mate.academy.security.AuthenticationService; import mate.academy.service.CinemaHallService; import mate.academy.service.MovieService; import mate.academy.service.MovieSessionService; +import mate.academy.service.OrderService; +import mate.academy.service.ShoppingCartService; public class Main { - public static void main(String[] args) { - MovieService movieService = null; + private static final Injector INJECTOR = Injector.getInstance("mate.academy"); + private static final String USER_EMAIL = "testemail@email.com"; + private static final String USER_PASSWORD = "testpassword"; + + public static void main(String[] args) throws RegistrationException { + MovieService movieService = + (MovieService) INJECTOR.getInstance(MovieService.class); Movie fastAndFurious = new Movie("Fast and Furious"); fastAndFurious.setDescription("An action film about street racing, heists, and spies."); @@ -27,7 +40,8 @@ public static void main(String[] args) { secondCinemaHall.setCapacity(200); secondCinemaHall.setDescription("second hall with capacity 200"); - CinemaHallService cinemaHallService = null; + CinemaHallService cinemaHallService = + (CinemaHallService) INJECTOR.getInstance(CinemaHallService.class); cinemaHallService.add(firstCinemaHall); cinemaHallService.add(secondCinemaHall); @@ -44,12 +58,29 @@ public static void main(String[] args) { yesterdayMovieSession.setMovie(fastAndFurious); yesterdayMovieSession.setShowTime(LocalDateTime.now().minusDays(1L)); - MovieSessionService movieSessionService = null; + MovieSessionService movieSessionService = + (MovieSessionService) INJECTOR.getInstance(MovieSessionService.class); movieSessionService.add(tomorrowMovieSession); movieSessionService.add(yesterdayMovieSession); System.out.println(movieSessionService.get(yesterdayMovieSession.getId())); System.out.println(movieSessionService.findAvailableSessions( fastAndFurious.getId(), LocalDate.now())); + + AuthenticationService authenticationService = + (AuthenticationService) INJECTOR.getInstance(AuthenticationService.class); + User user = authenticationService.register(USER_EMAIL, USER_PASSWORD); + + ShoppingCartService shoppingCartService = + (ShoppingCartService) INJECTOR.getInstance(ShoppingCartService.class); + shoppingCartService.addSession(yesterdayMovieSession, user); + shoppingCartService.addSession(tomorrowMovieSession, user); + + OrderService orderService = + (OrderService) INJECTOR.getInstance(OrderService.class); + Order order = orderService.completeOrder(shoppingCartService.getByUser(user)); + System.out.println(order); + List ordersHistory = orderService.getOrdersHistory(user); + System.out.println(ordersHistory); } } diff --git a/src/main/java/mate/academy/dao/OrderDao.java b/src/main/java/mate/academy/dao/OrderDao.java new file mode 100644 index 000000000..85d775eb0 --- /dev/null +++ b/src/main/java/mate/academy/dao/OrderDao.java @@ -0,0 +1,11 @@ +package mate.academy.dao; + +import java.util.List; +import mate.academy.model.Order; +import mate.academy.model.User; + +public interface OrderDao { + Order add(Order order); + + List getByUser(User user); +} diff --git a/src/main/java/mate/academy/dao/impl/CinemaHallDaoImpl.java b/src/main/java/mate/academy/dao/impl/CinemaHallDaoImpl.java index cd1ae9efb..8b4a01b38 100644 --- a/src/main/java/mate/academy/dao/impl/CinemaHallDaoImpl.java +++ b/src/main/java/mate/academy/dao/impl/CinemaHallDaoImpl.java @@ -9,16 +9,19 @@ import mate.academy.model.CinemaHall; import mate.academy.util.HibernateUtil; import org.hibernate.Session; +import org.hibernate.SessionFactory; import org.hibernate.Transaction; @Dao public class CinemaHallDaoImpl implements CinemaHallDao { + private final SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + @Override public CinemaHall add(CinemaHall cinemaHall) { Session session = null; Transaction transaction = null; try { - session = HibernateUtil.getSessionFactory().openSession(); + session = sessionFactory.openSession(); transaction = session.beginTransaction(); session.persist(cinemaHall); transaction.commit(); @@ -37,7 +40,7 @@ public CinemaHall add(CinemaHall cinemaHall) { @Override public Optional get(Long id) { - try (Session session = HibernateUtil.getSessionFactory().openSession()) { + try (Session session = sessionFactory.openSession()) { return Optional.ofNullable(session.get(CinemaHall.class, id)); } catch (Exception e) { throw new DataProcessingException("Can't get a cinema hall by id: " + id, e); @@ -46,7 +49,7 @@ public Optional get(Long id) { @Override public List getAll() { - try (Session session = HibernateUtil.getSessionFactory().openSession()) { + try (Session session = sessionFactory.openSession()) { CriteriaQuery criteriaQuery = session.getCriteriaBuilder() .createQuery(CinemaHall.class); criteriaQuery.from(CinemaHall.class); diff --git a/src/main/java/mate/academy/dao/impl/MovieDaoImpl.java b/src/main/java/mate/academy/dao/impl/MovieDaoImpl.java index 47e59a001..5561c65e6 100644 --- a/src/main/java/mate/academy/dao/impl/MovieDaoImpl.java +++ b/src/main/java/mate/academy/dao/impl/MovieDaoImpl.java @@ -9,16 +9,19 @@ import mate.academy.model.Movie; import mate.academy.util.HibernateUtil; import org.hibernate.Session; +import org.hibernate.SessionFactory; import org.hibernate.Transaction; @Dao public class MovieDaoImpl implements MovieDao { + private final SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + @Override public Movie add(Movie movie) { Transaction transaction = null; Session session = null; try { - session = HibernateUtil.getSessionFactory().openSession(); + session = sessionFactory.openSession(); transaction = session.beginTransaction(); session.persist(movie); transaction.commit(); @@ -37,7 +40,7 @@ public Movie add(Movie movie) { @Override public Optional get(Long id) { - try (Session session = HibernateUtil.getSessionFactory().openSession()) { + try (Session session = sessionFactory.openSession()) { return Optional.ofNullable(session.get(Movie.class, id)); } catch (Exception e) { throw new DataProcessingException("Can't get a movie by id: " + id, e); @@ -46,7 +49,7 @@ public Optional get(Long id) { @Override public List getAll() { - try (Session session = HibernateUtil.getSessionFactory().openSession()) { + try (Session session = sessionFactory.openSession()) { CriteriaQuery criteriaQuery = session.getCriteriaBuilder() .createQuery(Movie.class); criteriaQuery.from(Movie.class); diff --git a/src/main/java/mate/academy/dao/impl/MovieSessionDaoImpl.java b/src/main/java/mate/academy/dao/impl/MovieSessionDaoImpl.java index a573202d0..27beb751c 100644 --- a/src/main/java/mate/academy/dao/impl/MovieSessionDaoImpl.java +++ b/src/main/java/mate/academy/dao/impl/MovieSessionDaoImpl.java @@ -14,19 +14,21 @@ import mate.academy.model.MovieSession; import mate.academy.util.HibernateUtil; import org.hibernate.Session; +import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.query.Query; @Dao public class MovieSessionDaoImpl implements MovieSessionDao { private static final LocalTime END_OF_DAY = LocalTime.of(23, 59, 59); + private final SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); @Override public MovieSession add(MovieSession movieSession) { Transaction transaction = null; Session session = null; try { - session = HibernateUtil.getSessionFactory().openSession(); + session = sessionFactory.openSession(); transaction = session.beginTransaction(); session.persist(movieSession); transaction.commit(); @@ -45,7 +47,7 @@ public MovieSession add(MovieSession movieSession) { @Override public List findAvailableSessions(Long movieId, LocalDate date) { - try (Session session = HibernateUtil.getSessionFactory().openSession()) { + try (Session session = sessionFactory.openSession()) { CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder(); CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(MovieSession.class); @@ -66,7 +68,7 @@ public List findAvailableSessions(Long movieId, LocalDate date) { @Override public Optional get(Long id) { - try (Session session = HibernateUtil.getSessionFactory().openSession()) { + try (Session session = sessionFactory.openSession()) { Query query = session.createQuery("FROM MovieSession ms " + "JOIN FETCH ms.movie m " + "JOIN FETCH ms.cinemaHall ch " diff --git a/src/main/java/mate/academy/dao/impl/OrderDaoImpl.java b/src/main/java/mate/academy/dao/impl/OrderDaoImpl.java new file mode 100644 index 000000000..72a8df00d --- /dev/null +++ b/src/main/java/mate/academy/dao/impl/OrderDaoImpl.java @@ -0,0 +1,59 @@ +package mate.academy.dao.impl; + +import java.util.List; +import mate.academy.dao.OrderDao; +import mate.academy.exception.DataProcessingException; +import mate.academy.lib.Dao; +import mate.academy.model.Order; +import mate.academy.model.User; +import mate.academy.util.HibernateUtil; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; + +@Dao +public class OrderDaoImpl implements OrderDao { + private final SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + + @Override + public Order add(Order order) { + Session session = null; + Transaction transaction = null; + try { + session = sessionFactory.openSession(); + transaction = session.beginTransaction(); + session.persist(order); + transaction.commit(); + } catch (Exception ex) { + if (transaction != null) { + transaction.rollback(); + } + throw new DataProcessingException( + String.format("Can`t add a new order: %s to the DB", order), ex); + } finally { + if (session != null) { + session.close(); + } + } + return order; + } + + @Override + public List getByUser(User user) { + try (Session session = sessionFactory.openSession()) { + return session.createQuery("FROM Order o " + + "JOIN FETCH o.tickets t " + + "JOIN FETCH t.movieSession ms " + + "JOIN FETCH ms.movie " + + "JOIN FETCH ms.cinemaHall " + + "JOIN FETCH o.user u " + + "WHERE u.id = :userId", Order.class) + .setParameter("userId", user.getId()) + .getResultList(); + } catch (Exception ex) { + throw new DataProcessingException( + String.format("Can`t get orders by user: %s", user), ex + ); + } + } +} diff --git a/src/main/java/mate/academy/dao/impl/ShoppingCartDaoImpl.java b/src/main/java/mate/academy/dao/impl/ShoppingCartDaoImpl.java index fa1380642..b0efc6a5b 100644 --- a/src/main/java/mate/academy/dao/impl/ShoppingCartDaoImpl.java +++ b/src/main/java/mate/academy/dao/impl/ShoppingCartDaoImpl.java @@ -7,17 +7,20 @@ import mate.academy.model.User; import mate.academy.util.HibernateUtil; import org.hibernate.Session; +import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.query.Query; @Dao public class ShoppingCartDaoImpl implements ShoppingCartDao { + private final SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + @Override public ShoppingCart add(ShoppingCart shoppingCart) { Session session = null; Transaction transaction = null; try { - session = HibernateUtil.getSessionFactory().openSession(); + session = sessionFactory.openSession(); transaction = session.beginTransaction(); User managedUser = session.merge(shoppingCart.getUser()); shoppingCart.setUser(managedUser); @@ -38,7 +41,7 @@ public ShoppingCart add(ShoppingCart shoppingCart) { @Override public ShoppingCart getByUser(User user) { - try (Session session = HibernateUtil.getSessionFactory().openSession()) { + try (Session session = sessionFactory.openSession()) { Query query = session.createQuery("FROM ShoppingCart sc " + "LEFT JOIN FETCH sc.tickets t " + "LEFT JOIN FETCH t.movieSession ms " @@ -57,7 +60,7 @@ public void update(ShoppingCart shoppingCart) { Session session = null; Transaction transaction = null; try { - session = HibernateUtil.getSessionFactory().openSession(); + session = sessionFactory.openSession(); transaction = session.beginTransaction(); session.update(shoppingCart); transaction.commit(); diff --git a/src/main/java/mate/academy/dao/impl/TicketDaoImpl.java b/src/main/java/mate/academy/dao/impl/TicketDaoImpl.java index ad7a494a5..88d0967bb 100644 --- a/src/main/java/mate/academy/dao/impl/TicketDaoImpl.java +++ b/src/main/java/mate/academy/dao/impl/TicketDaoImpl.java @@ -6,16 +6,19 @@ import mate.academy.model.Ticket; import mate.academy.util.HibernateUtil; import org.hibernate.Session; +import org.hibernate.SessionFactory; import org.hibernate.Transaction; @Dao public class TicketDaoImpl implements TicketDao { + private final SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + @Override public Ticket add(Ticket ticket) { Session session = null; Transaction transaction = null; try { - session = HibernateUtil.getSessionFactory().openSession(); + session = sessionFactory.openSession(); transaction = session.beginTransaction(); session.persist(ticket); transaction.commit(); diff --git a/src/main/java/mate/academy/dao/impl/UserDaoImpl.java b/src/main/java/mate/academy/dao/impl/UserDaoImpl.java index f0de09673..27b46c90f 100644 --- a/src/main/java/mate/academy/dao/impl/UserDaoImpl.java +++ b/src/main/java/mate/academy/dao/impl/UserDaoImpl.java @@ -7,17 +7,20 @@ import mate.academy.model.User; import mate.academy.util.HibernateUtil; import org.hibernate.Session; +import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.query.Query; @Dao public class UserDaoImpl implements UserDao { + private final SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + @Override public User add(User user) { Session session = null; Transaction transaction = null; try { - session = HibernateUtil.getSessionFactory().openSession(); + session = sessionFactory.openSession(); transaction = session.beginTransaction(); session.persist(user); transaction.commit(); @@ -36,7 +39,7 @@ public User add(User user) { @Override public Optional findByEmail(String email) { - try (Session session = HibernateUtil.getSessionFactory().openSession()) { + try (Session session = sessionFactory.openSession()) { Query query = session.createQuery("FROM User u " + "WHERE u.email = :email", User.class); query.setParameter("email", email); diff --git a/src/main/java/mate/academy/model/Order.java b/src/main/java/mate/academy/model/Order.java new file mode 100644 index 000000000..47ee1a2bc --- /dev/null +++ b/src/main/java/mate/academy/model/Order.java @@ -0,0 +1,82 @@ +package mate.academy.model; + +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.OneToMany; +import jakarta.persistence.Table; +import java.time.LocalDateTime; +import java.util.List; +import org.hibernate.annotations.CreationTimestamp; + +@Entity +@Table(name = "orders") +public class Order { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @OneToMany + private List tickets; + + @CreationTimestamp + private LocalDateTime orderDateTime; + + @ManyToOne + @JoinColumn(name = "user_id") + private User user; + + public Order() { + } + + public Order(List tickets, LocalDateTime orderDateTime, User user) { + this.tickets = tickets; + this.orderDateTime = orderDateTime; + this.user = user; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public List getTickets() { + return tickets; + } + + public void setTickets(List tickets) { + this.tickets = tickets; + } + + public LocalDateTime getOrderDateTime() { + return orderDateTime; + } + + public void setOrderDateTime(LocalDateTime orderDateTime) { + this.orderDateTime = orderDateTime; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + @Override + public String toString() { + return "Order{" + + "id=" + id + + ", tickets=" + tickets + + ", orderDateTime=" + orderDateTime + + ", user=" + user + + '}'; + } +} diff --git a/src/main/java/mate/academy/service/OrderService.java b/src/main/java/mate/academy/service/OrderService.java new file mode 100644 index 000000000..6c66484ec --- /dev/null +++ b/src/main/java/mate/academy/service/OrderService.java @@ -0,0 +1,12 @@ +package mate.academy.service; + +import java.util.List; +import mate.academy.model.Order; +import mate.academy.model.ShoppingCart; +import mate.academy.model.User; + +public interface OrderService { + Order completeOrder(ShoppingCart shoppingCart); + + List getOrdersHistory(User user); +} diff --git a/src/main/java/mate/academy/service/impl/OrderServiceImpl.java b/src/main/java/mate/academy/service/impl/OrderServiceImpl.java new file mode 100644 index 000000000..87fef98f8 --- /dev/null +++ b/src/main/java/mate/academy/service/impl/OrderServiceImpl.java @@ -0,0 +1,36 @@ +package mate.academy.service.impl; + +import java.time.LocalDateTime; +import java.util.List; +import mate.academy.dao.OrderDao; +import mate.academy.lib.Inject; +import mate.academy.lib.Service; +import mate.academy.model.Order; +import mate.academy.model.ShoppingCart; +import mate.academy.model.User; +import mate.academy.service.OrderService; +import mate.academy.service.ShoppingCartService; + +@Service +public class OrderServiceImpl implements OrderService { + @Inject + private OrderDao orderDao; + + @Inject + private ShoppingCartService shoppingCartService; + + @Override + public Order completeOrder(ShoppingCart shoppingCart) { + Order order = new Order(); + order.setUser(shoppingCart.getUser()); + order.setTickets(List.copyOf(shoppingCart.getTickets())); + order.setOrderDateTime(LocalDateTime.now()); + shoppingCartService.clearShoppingCart(shoppingCart); + return orderDao.add(order); + } + + @Override + public List getOrdersHistory(User user) { + return orderDao.getByUser(user); + } +} diff --git a/src/main/resources/hibernate.cfg.xml b/src/main/resources/hibernate.cfg.xml new file mode 100644 index 000000000..c0d0d252b --- /dev/null +++ b/src/main/resources/hibernate.cfg.xml @@ -0,0 +1,24 @@ + + + + + org.hibernate.dialect.MySQLDialect + jdbc:mysql://localhost:3306/cinema?createDatabaseIfNotExist=true + com.mysql.cj.jdbc.Driver + USE-YOUR-DB-USERNAME + USE-YOUR-DB-PASSWORD + true + true + create-drop + + + + + + + + + +