diff --git a/data.mv.db b/data.mv.db new file mode 100644 index 0000000..8dd6ecb Binary files /dev/null and b/data.mv.db differ diff --git a/src/main/java/ru/ulstu/is/sbapp/Models/Customer.java b/src/main/java/ru/ulstu/is/sbapp/Models/Customer.java new file mode 100644 index 0000000..81af58e --- /dev/null +++ b/src/main/java/ru/ulstu/is/sbapp/Models/Customer.java @@ -0,0 +1,99 @@ +package ru.ulstu.is.sbapp.Models; + + +import javax.persistence.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +@Entity +public class Customer +{ + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + @Column(nullable = false) + private String first_name; + @Column(nullable = false) + private String last_name; + @Column() + private String middle_name; + + @ManyToMany + private List movies; + + + public Customer() + { + + } + public Customer(String fullName) + { + String[] partsName = fullName.split(" "); + this.first_name = partsName[0]; + this.last_name = partsName[1]; + if(partsName.length == 3) + { + this.middle_name = partsName[2]; + } + this.movies = new ArrayList<>(); + } + + public Long getId() + { + return id; + } + + public String getFirst_name() + { + return first_name; + } + + public void setFirst_name(String first_name) + { + this.first_name = first_name; + } + + public String getLast_name() + { + return last_name; + } + + public void setLast_name(String last_name) + { + this.last_name = last_name; + } + + public String getMiddle_name() + { + + return middle_name.isBlank() ? null : middle_name; + } + + public void setMiddle_name(String middle_name) + { + if(!middle_name.isBlank()) + { + this.middle_name = middle_name; + } + } + + public List getMovies() + { + return movies; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Customer customer = (Customer) o; + return Objects.equals(id, customer.id); + } + + @Override + public String toString() + { + return "Customer: " + "ID: " + id + " | FirstName: " + first_name + " | LastName: " + last_name + " | MiddleName: " + middle_name; + } +} diff --git a/src/main/java/ru/ulstu/is/sbapp/Models/Genre.java b/src/main/java/ru/ulstu/is/sbapp/Models/Genre.java new file mode 100644 index 0000000..56373d9 --- /dev/null +++ b/src/main/java/ru/ulstu/is/sbapp/Models/Genre.java @@ -0,0 +1,62 @@ +package ru.ulstu.is.sbapp.Models; + +import javax.persistence.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +@Entity +public class Genre +{ + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + @Column(nullable = false) + private String name; + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "genre") + private List movies; + + public Genre() + { + + } + public Genre(String name) + { + this.name = name; + this.movies = new ArrayList<>(); + } + + public Long getId() + { + return id; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public List getMovies() + { + return movies; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Genre genre = (Genre) o; + return Objects.equals(id, genre.id); + } + + @Override + public String toString() + { + return "Genre: " + " ID: " + id + " | Name: " + name; + } +} diff --git a/src/main/java/ru/ulstu/is/sbapp/Models/Movie.java b/src/main/java/ru/ulstu/is/sbapp/Models/Movie.java new file mode 100644 index 0000000..66601bd --- /dev/null +++ b/src/main/java/ru/ulstu/is/sbapp/Models/Movie.java @@ -0,0 +1,102 @@ +package ru.ulstu.is.sbapp.Models; + +import javax.persistence.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +@Entity +public class Movie +{ + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + @Column(nullable = false) + private String title; + @Column(nullable = false) + private int length; + @Column(nullable = false) + private double score; + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "genre_fk") + private Genre genre; + + @ManyToMany(mappedBy = "movies") + private List customers; + + public Movie() + { + + } + public Movie(String title, int length, double score, Genre genre) + { + this.title = title; + this.length = length; + this.score = score; + this.genre = genre; + this.customers = new ArrayList<>(); + } + + public Long getId() + { + return id; + } + + public String getTitle() + { + return title; + } + + public void setTitle(String title) + { + this.title = title; + } + + public String getLength() + { + return Integer.toString(length); + } + + public void setLength(int length) + { + this.length = length; + } + + public String getScore() + { + return Double.toString(score); + } + + public void setScore(Double score) + { + this.score = score; + } + + public Genre getGenre() + { + return genre; + } + + public void setGenre(Genre genre) + { + this.genre = genre; + } + + public List getCustomers() + { + return customers; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Movie movie = (Movie) o; + return Objects.equals(id, movie.id); + } + + @Override + public String toString() + { + return "Movie: " + " ID: " + id + " | Title: " + title + " | Length: " + length + " | Score: " + score; + } +} diff --git a/src/main/java/ru/ulstu/is/sbapp/Services/CustomerService.java b/src/main/java/ru/ulstu/is/sbapp/Services/CustomerService.java new file mode 100644 index 0000000..b3f75b6 --- /dev/null +++ b/src/main/java/ru/ulstu/is/sbapp/Services/CustomerService.java @@ -0,0 +1,75 @@ +package ru.ulstu.is.sbapp.Services; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; +import ru.ulstu.is.sbapp.Models.Customer; + +import javax.persistence.EntityManager; +import javax.persistence.EntityNotFoundException; +import javax.persistence.PersistenceContext; +import java.util.List; + +@Service +public class CustomerService +{ + @PersistenceContext + private EntityManager em; + + @Transactional + public Customer addCustomer(String fullName) + { + if(!StringUtils.hasText(fullName)) + { + throw new IllegalArgumentException("Customer's name or surname is missing"); + } + final Customer customer = new Customer(fullName); + em.persist(customer); + return customer; + } + + @Transactional(readOnly = true) + public Customer findCustomer(Long id) + { + final Customer customer = em.find(Customer.class,id); + if(customer == null) + { + throw new EntityNotFoundException(String.format("Customer with id [%s] is not found", id)); + } + return customer; + } + + @Transactional(readOnly = true) + public List findAllCustomers() + { + return em.createQuery("select c from Customer c",Customer.class).getResultList(); + } + + @Transactional + public Customer updateCustomer(Long id, String firstName, String lastName, String middleName) + { + if(!StringUtils.hasText(firstName) || !StringUtils.hasText(lastName)) + { + throw new IllegalArgumentException("Customer's name or surname is missing"); + } + final Customer specificCustomer = findCustomer(id); + specificCustomer.setFirst_name(firstName); + specificCustomer.setLast_name(lastName); + specificCustomer.setMiddle_name(middleName); + return em.merge(specificCustomer); + } + + @Transactional + public Customer deleteCustomer(Long id) + { + final Customer specificCustomer = findCustomer(id); + em.remove(specificCustomer); + return specificCustomer; + } + + @Transactional + public void deleteAllCustomers() + { + em.createQuery("delete from Customer").executeUpdate(); + } +} diff --git a/src/main/java/ru/ulstu/is/sbapp/Services/GenreService.java b/src/main/java/ru/ulstu/is/sbapp/Services/GenreService.java new file mode 100644 index 0000000..9ae9618 --- /dev/null +++ b/src/main/java/ru/ulstu/is/sbapp/Services/GenreService.java @@ -0,0 +1,73 @@ +package ru.ulstu.is.sbapp.Services; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; +import ru.ulstu.is.sbapp.Models.Genre; + +import javax.persistence.EntityManager; +import javax.persistence.EntityNotFoundException; +import javax.persistence.PersistenceContext; +import java.util.List; + +@Service +public class GenreService +{ + @PersistenceContext + private EntityManager em; + + @Transactional + public Genre addGenre(String name) + { + if(!StringUtils.hasText(name)) + { + throw new IllegalArgumentException("Genre's name is missing"); + } + final Genre genre = new Genre(name); + em.persist(genre); + return genre; + } + + @Transactional(readOnly = true) + public Genre findGenre(Long id) + { + final Genre specificGenre = em.find(Genre.class,id); + if(specificGenre == null) + { + throw new EntityNotFoundException(String.format("Genre with id [%s] is not found", id)); + } + return specificGenre; + } + + @Transactional(readOnly = true) + public List findAllGenres() + { + return em.createQuery("select g from Genre g",Genre.class).getResultList(); + } + + @Transactional + public Genre updateGenre(Long id, String name) + { + if(StringUtils.hasText(name)) + { + throw new IllegalArgumentException("Genre's name is missing"); + } + final Genre specificGenre = findGenre(id); + specificGenre.setName(name); + return em.merge(specificGenre); + } + + @Transactional + public Genre deleteGenre(Long id) + { + final Genre specificGenre = findGenre(id); + em.remove(specificGenre); + return specificGenre; + } + + @Transactional + public void deleteAllGenres() + { + em.createQuery("delete from Genre").executeUpdate(); + } +} diff --git a/src/main/java/ru/ulstu/is/sbapp/Services/MovieService.java b/src/main/java/ru/ulstu/is/sbapp/Services/MovieService.java new file mode 100644 index 0000000..ddf18bb --- /dev/null +++ b/src/main/java/ru/ulstu/is/sbapp/Services/MovieService.java @@ -0,0 +1,85 @@ +package ru.ulstu.is.sbapp.Services; + + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; +import ru.ulstu.is.sbapp.Models.Movie; +import ru.ulstu.is.sbapp.Models.Customer; +import ru.ulstu.is.sbapp.Models.Genre; +import javax.persistence.EntityManager; +import javax.persistence.EntityNotFoundException; +import javax.persistence.PersistenceContext; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Service +public class MovieService +{ + @PersistenceContext + private EntityManager em; + + @Transactional + public Movie addMovie(String title, int length, double score, Genre genre, Customer customer) + { + if(!StringUtils.hasText(title) || length == 0 || score == 0 || genre == null || customer == null) + { + throw new IllegalArgumentException("Some of the movie's properties are incorrect."); + } + final Movie movie = new Movie(title,length,score,genre); + movie.getGenre().getMovies().add(movie); + customer.getMovies().add(movie); + + em.persist(movie); + return movie; + } + + @Transactional(readOnly = true) + public Movie findMovie(Long id) + { + final Movie specificMovie = em.find(Movie.class, id); + if(specificMovie == null) + { + throw new EntityNotFoundException(String.format("Movie with id [%s] is not found", id)); + } + return specificMovie; + } + + @Transactional(readOnly = true) + public List findAllMovies() + { + return em.createQuery("select m from Movie m",Movie.class).getResultList(); + } + + @Transactional + public Movie updateMovie(Long id, String title, int length, double score, Genre genre) + { + if(!StringUtils.hasText(title) || length == 0 || score == 0 || genre == null) + { + throw new IllegalArgumentException("Some of the movie's properties are incorrect."); + } + final Movie specificMovie = findMovie(id); + specificMovie.setLength(length); + specificMovie.setGenre(genre); + specificMovie.setTitle(title); + specificMovie.setScore(score); + return em.merge(specificMovie); + } + + @Transactional + public Movie deleteMovie(Long id, Customer customer) + { + final Movie specificMovie = findMovie(id); + specificMovie.getGenre().getMovies().remove(specificMovie); + customer.getMovies().remove(specificMovie); + em.remove(specificMovie); + return specificMovie; + } + + @Transactional + public void deleteAllMovies() + { + em.createQuery("delete from Movie").executeUpdate(); + } +} diff --git a/src/test/java/ru/ulstu/is/sbapp/JpaCustomerTests.java b/src/test/java/ru/ulstu/is/sbapp/JpaCustomerTests.java new file mode 100644 index 0000000..d90f859 --- /dev/null +++ b/src/test/java/ru/ulstu/is/sbapp/JpaCustomerTests.java @@ -0,0 +1,70 @@ +package ru.ulstu.is.sbapp; + +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import ru.ulstu.is.sbapp.Models.Customer; +import ru.ulstu.is.sbapp.Services.CustomerService; + +import javax.persistence.EntityNotFoundException; +import java.util.List; + +@SpringBootTest +public class JpaCustomerTests +{ + private static final Logger log = LoggerFactory.getLogger(JpaCustomerTests.class); + + @Autowired + private CustomerService customerService; + + @Test + void testCustomerCreate() + { + customerService.deleteAllCustomers(); + final Customer customer = customerService.addCustomer("Nikita Lisov"); + log.info(customer.toString()); + Assertions.assertNotNull(customer.getId()); + } + + @Test + void testCustomerRead() + { + customerService.deleteAllCustomers(); + final Customer customer = customerService.addCustomer("Nikita Lisov"); + log.info(customer.toString()); + final Customer findCustomer = customerService.findCustomer(customer.getId()); + log.info(findCustomer.toString()); + Assertions.assertEquals(customer, findCustomer); + } + + @Test + void testCustomerReadNotFound() + { + customerService.deleteAllCustomers(); + Assertions.assertThrows(EntityNotFoundException.class, () -> customerService.findCustomer(-1L)); + } + + @Test + void testCustomerReadAll() + { + customerService.deleteAllCustomers(); + customerService.addCustomer("Nikita Lisov"); + customerService.addCustomer("Evelina Aust Sergeevna"); + final List customers = customerService.findAllCustomers(); + log.info(customers.toString()); + Assertions.assertEquals(customers.size(), 2); + } + + @Test + void testCustomerReadAllEmpty() + { + customerService.deleteAllCustomers(); + final List customers = customerService.findAllCustomers(); + log.info(customers.toString()); + Assertions.assertEquals(customers.size(), 0); + } +} diff --git a/src/test/java/ru/ulstu/is/sbapp/JpaGenreTests.java b/src/test/java/ru/ulstu/is/sbapp/JpaGenreTests.java new file mode 100644 index 0000000..6413122 --- /dev/null +++ b/src/test/java/ru/ulstu/is/sbapp/JpaGenreTests.java @@ -0,0 +1,69 @@ +package ru.ulstu.is.sbapp; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import ru.ulstu.is.sbapp.Models.Genre; +import ru.ulstu.is.sbapp.Services.GenreService; + +import javax.persistence.EntityNotFoundException; +import java.util.List; + +@SpringBootTest +public class JpaGenreTests +{ + private static final Logger log = LoggerFactory.getLogger(JpaCustomerTests.class); + + @Autowired + private GenreService genreService; + + @Test + void testCustomerCreate() + { + genreService.deleteAllGenres(); + final Genre genre = genreService.addGenre("Fantasy"); + log.info(genre.toString()); + Assertions.assertNotNull(genre.getId()); + } + + @Test + void testCustomerRead() + { + genreService.deleteAllGenres(); + final Genre genre = genreService.addGenre("Nikita Lisov"); + log.info(genre.toString()); + final Genre findCustomer = genreService.findGenre(genre.getId()); + log.info(findCustomer.toString()); + Assertions.assertEquals(genre, findCustomer); + } + + @Test + void testCustomerReadNotFound() + { + genreService.deleteAllGenres(); + Assertions.assertThrows(EntityNotFoundException.class, () -> genreService.findGenre(-1L)); + } + + @Test + void testCustomerReadAll() + { + genreService.deleteAllGenres(); + genreService.addGenre("Nikita Lisov"); + genreService.addGenre("Evelina Aust Sergeevna"); + final List customers = genreService.findAllGenres(); + log.info(customers.toString()); + Assertions.assertEquals(customers.size(), 2); + } + + @Test + void testCustomerReadAllEmpty() + { + genreService.deleteAllGenres(); + final List customers = genreService.findAllGenres(); + log.info(customers.toString()); + Assertions.assertEquals(customers.size(), 0); + } +} diff --git a/src/test/java/ru/ulstu/is/sbapp/JpaMovieTests.java b/src/test/java/ru/ulstu/is/sbapp/JpaMovieTests.java new file mode 100644 index 0000000..62b8a9c --- /dev/null +++ b/src/test/java/ru/ulstu/is/sbapp/JpaMovieTests.java @@ -0,0 +1,167 @@ +package ru.ulstu.is.sbapp; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import ru.ulstu.is.sbapp.Services.MovieService; +import ru.ulstu.is.sbapp.Models.Movie; +import ru.ulstu.is.sbapp.Models.Customer; +import ru.ulstu.is.sbapp.Services.CustomerService; +import ru.ulstu.is.sbapp.Models.Genre; +import ru.ulstu.is.sbapp.Services.GenreService; + +import javax.persistence.EntityNotFoundException; +import java.util.List; + +@SpringBootTest +public class JpaMovieTests +{ + private static final Logger log = LoggerFactory.getLogger(JpaCustomerTests.class); + + @Autowired + private MovieService movieService; + @Autowired + private GenreService genreService; + @Autowired + private CustomerService customerService; + + @Test + void testMovieCreate() + { + movieService.deleteAllMovies(); + customerService.deleteAllCustomers(); + genreService.deleteAllGenres(); + + final Genre genre = genreService.addGenre("Fantasy"); + log.info(genre.toString()); + + final Customer customer = customerService.addCustomer("Nikita Lisov"); + log.info(customer.toString()); + + final Movie movie = movieService.addMovie("Arcane",36,4.5, genre, customer); + log.info(movie.toString()); + + Assertions.assertNotNull(movie.getId()); + } + + @Test + void testMovieRead() + { + movieService.deleteAllMovies(); + customerService.deleteAllCustomers(); + genreService.deleteAllGenres(); + + final Genre genre = genreService.addGenre("Fantasy"); + log.info(genre.toString()); + + final Customer customer = customerService.addCustomer("Nikita Lisov"); + log.info(customer.toString()); + + final Movie movie = movieService.addMovie("Arcane",36,4.5, genre, customer); + log.info(movie.toString()); + + + final Movie findMovie = movieService.findMovie(movie.getId()); + log.info(findMovie.toString()); + + Assertions.assertEquals(movie,findMovie); + } + + @Test + void testCheckMoviesCustomer() + { + movieService.deleteAllMovies(); + customerService.deleteAllCustomers(); + genreService.deleteAllGenres(); + + final Genre genre = genreService.addGenre("Fantasy"); + log.info(genre.toString()); + + final Customer customer = customerService.addCustomer("Nikita Lisov"); + log.info(customer.toString()); + final Movie movie = movieService.addMovie("Arcane",36,4.5, genre, customer); + log.info(movie.toString()); + log.info(customer.getMovies().toString()); + + final List movies = movieService.findAllMovies(); + log.info(movies.toString()); + + Assertions.assertEquals(movies.size(),customer.getMovies().size()); + } + + @Test + void testCheckMoviesGenre() + { + movieService.deleteAllMovies(); + customerService.deleteAllCustomers(); + genreService.deleteAllGenres(); + + final Genre genre = genreService.addGenre("Fantasy"); + log.info(genre.toString()); + + final Customer customer = customerService.addCustomer("Nikita Lisov"); + log.info(customer.toString()); + + final Movie movie = movieService.addMovie("Arcane",36,4.5, genre, customer); + log.info(movie.toString()); + + final List movies = movieService.findAllMovies(); + log.info(movies.toString()); + + Assertions.assertEquals(movies.size(),genre.getMovies().size()); + } + + @Test + void testCheckMultipleMovies() + { + movieService.deleteAllMovies(); + customerService.deleteAllCustomers(); + genreService.deleteAllGenres(); + + final Genre genre = genreService.addGenre("Fantasy"); + log.info(genre.toString()); + + final Customer customer1 = customerService.addCustomer("Nikita Lisov"); + log.info(customer1.toString()); + + final Customer customer2 = customerService.addCustomer("Evelina Potter"); + log.info(customer2.toString()); + + final Movie movie1 = movieService.addMovie("Arcane",36,4.5, genre, customer1); + log.info(movie1.toString()); + + final Movie movie2 = movieService.addMovie("Harry Potter",128,10.0, genre, customer2); + log.info(movie2.toString()); + + final List movies = movieService.findAllMovies(); + log.info(movies.toString()); + + Assertions.assertEquals(movies.size(),customer1.getMovies().size() + customer2.getMovies().size()); + } + + @Test + void testMovieReadNotFound() + { + movieService.deleteAllMovies(); + customerService.deleteAllCustomers(); + genreService.deleteAllGenres(); + + Assertions.assertThrows(EntityNotFoundException.class, () -> movieService.findMovie(-1L)); + } + + @Test + void testMovieReadAllEmpty() + { + movieService.deleteAllMovies(); + customerService.deleteAllCustomers(); + genreService.deleteAllGenres(); + + final List movies = movieService.findAllMovies(); + log.info(movies.toString()); + Assertions.assertEquals(movies.size(),0); + + } +} diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties new file mode 100644 index 0000000..81734b8 --- /dev/null +++ b/src/test/resources/application.properties @@ -0,0 +1,6 @@ +spring.datasource.url=jdbc:h2:mem:testdb +spring.datasource.driverClassName=org.h2.Driver +spring.datasource.username=sa +spring.datasource.password=password +spring.jpa.database-platform=org.hibernate.dialect.H2Dialect +spring.jpa.hibernate.ddl-auto=create-drop \ No newline at end of file