diff --git a/README.md b/README.md index 5150e50f..2ab82cb2 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +[![Review Assignment Due Date](https://classroom.github.com/assets/deadline-readme-button-22041afd0340ce965d47ae6ef1cefeee28c7c493a6346c4f15d667ab976d596c.svg)](https://classroom.github.com/a/_uV8Mn8f) # 📘 Projektarbete: JPA + Hibernate med GitHub-flöde Projektet genomförs som antingen en Java CLI-applikation eller med hjĂ€lp av JavaFX om ni vill ha ett grafiskt grĂ€nssnitt. @@ -9,11 +10,11 @@ Kommunikation med databasen ska ske med JPA och Hibernate, enligt code first-met ## đŸ—“ïž Veckoplanering med Checklista ### ✅ Vecka 1 – GrundlĂ€ggning och struktur -- [ ] Klona GitHub-repo -- [ ] Konfigurera persistence.xml eller anvĂ€nd PersistenceConfiguration i kod -- [ ] Skapa entiteter och verifiera tabellgenerering -- [ ] LĂ€gg till relationer (One-to-Many, Many-to-Many) -- [ ] Arbeta pĂ„ feature-branches och anvĂ€nd pull requests för kodgranskning +- [x] Klona GitHub-repo +- [x] Konfigurera persistence.xml eller anvĂ€nd PersistenceConfiguration i kod +- [x] Skapa entiteter och verifiera tabellgenerering +- [x] LĂ€gg till relationer (One-to-Many, Many-to-Many) +- [x] Arbeta pĂ„ feature-branches och anvĂ€nd pull requests för kodgranskning ### ✅ Vecka 2 – Funktionalitet och relationer - [ ] Dela upp funktioner mellan gruppmedlemmar diff --git a/src/main/java/org/example/BaseEntity.java b/src/main/java/org/example/BaseEntity.java new file mode 100644 index 00000000..b4437f17 --- /dev/null +++ b/src/main/java/org/example/BaseEntity.java @@ -0,0 +1,19 @@ +package org.example; + +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.MappedSuperclass; + +@MappedSuperclass +public abstract class BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + public Long getId() { + return id; + } + +} diff --git a/src/main/java/org/example/BaseRepositoryImpl.java b/src/main/java/org/example/BaseRepositoryImpl.java new file mode 100644 index 00000000..e9c846b2 --- /dev/null +++ b/src/main/java/org/example/BaseRepositoryImpl.java @@ -0,0 +1,93 @@ +package org.example; + +import jakarta.persistence.EntityManager; + +import java.util.Optional; + +public class BaseRepositoryImpl implements Repository { + + protected EntityManager em; + protected Class entityClass; + + + public BaseRepositoryImpl(Class entityClass) { + this.entityClass = entityClass; + } + + public void setEntityManager(EntityManager em) { + this.em = em; + } + + + + @Override + public T save(T entity) { + if (entity == null) { + throw new IllegalArgumentException("Entity cannot be null"); + } + if (entity.getId() == null) { + em.persist(entity); + return entity; + } else { + return em.merge(entity); + } + } + + + + public EntityManager getEntityManager() { + return em; + } + + @Override + public Optional findById(Long id) { + return Optional.ofNullable(em.find(entityClass, id)); + } + + @Override + public void delete(T entity) { + em.remove(em.contains(entity) ? entity : em.merge(entity)); + } + + @Override + public void deleteById(Long id) { + T entity = em.find(entityClass, id); + if (entity != null) { + em.remove(entity); + } + } + + @Override + public Iterable findAll() { + return em.createQuery( + "select e from " + entityClass.getSimpleName() + " e", entityClass + ).getResultList(); + } + + @Override + public boolean existsById(Long id) { + Long count = em.createQuery( + "select count(e) from " + entityClass.getSimpleName() + " e where e.id = :id", + Long.class + ).setParameter("id", id).getSingleResult(); + return count > 0; + + } + + @Override + public long count() { + + return em.createQuery("select count(e) from " + entityClass.getSimpleName() + " e", Long.class).getSingleResult(); + } + + @Override + public void flush() { + em.flush(); + } + + @Override + public void clear() { + em.clear(); + } + +} diff --git a/src/main/java/org/example/BusinessException.java b/src/main/java/org/example/BusinessException.java new file mode 100644 index 00000000..90b73190 --- /dev/null +++ b/src/main/java/org/example/BusinessException.java @@ -0,0 +1,6 @@ +package org.example; + +public class BusinessException extends Throwable { + public BusinessException(String s) { + } +} diff --git a/src/main/java/org/example/CLI.java b/src/main/java/org/example/CLI.java new file mode 100644 index 00000000..5f672d02 --- /dev/null +++ b/src/main/java/org/example/CLI.java @@ -0,0 +1,335 @@ +package org.example; + +public class CLI { + DirectorService directorService; + FilmService filmService; + SeriesService seriesService; + + void cliStart(DirectorService directorService, FilmService filmService, SeriesService seriesService){ + this.directorService = directorService; + this.filmService = filmService; + this.seriesService = seriesService; + + mainMenu(); + } + + void mainMenu() { + while(true) { + + System.out.println(""" + Welcome to the Film Database! + + Please select a category to view below: + + 1. Directors + 2. Films + 3. Series + + 4. Exit + + """); + switch (IO.readln()) { + case "1" -> directorMenu(); + case "2" -> filmMenu(); + case "3" -> seriesMenu(); + case "4" -> System.exit(0); + default -> invalidInput(); + } + } + } + + private static void invalidInput() { + System.out.println("Invalid input!" + + "\nPlease enter the number of the option you wish to choose"); + } + + private void directorMenu() { + System.out.println(""" + You are in the Director Menu. + + Please select an action below: + + 1. Create new entry + 2. List entries + 3. List specific entry + 4. Update existing entry + + 5. Exit + + """); + switch (IO.readln()){ + case "1" -> createDirector(); + case "2" -> listDirectors(); + case "3" -> listSpecificDirector(); + case "4" -> updateDirector(); + case "5" -> mainMenu(); + default -> invalidInput(); + } + } + + private void createDirector() { + String name; + String country; + int birthYear; + Integer yearOfDeath = null; + try { + name = IO.readln("Enter the full name of the Director: "); + country = IO.readln("Enter the country of the Director: "); + birthYear = Integer.parseInt(IO.readln("Enter the birth year of the Director: ")); + try { + yearOfDeath = Integer.valueOf(IO.readln("Enter the year of death of the Director." + + "\nIf they're alive, leave blank: ")); + } catch (NumberFormatException _) { + } + + Director newDirector = new Director(); + newDirector.setName(name); + newDirector.setCountry(country); + newDirector.setBirthYear(birthYear); + newDirector.setYearOfDeath(yearOfDeath); + directorService.create(newDirector); + + } catch (NumberFormatException e) { + System.out.println("Invalid input!"); + } + } + + private void listDirectors() { + IO.println(directorService.findAll()); + } + + private void listSpecificDirector() { + String input = IO.readln("Enter the ID or name of the Director: "); + Director d; + try{ + d = directorService.findDirectorId(Long.valueOf(input)); + } catch (NumberFormatException e) { + d = directorService.findDirectorName(input); + } + + + IO.println("Name: " + d.getName() + + "\nCountry: " + d.getCountry() + + "\nYear of birth: " + d.getBirthYear() + + "\nYear of death: " + d.getYearOfDeath() + + "Films:\n" + + d.getFilms() + + "\n\nSeries:\n" + + d.getSeries()); + } + + private void updateDirector() { + Long id = Long.valueOf(IO.readln("Enter the ID of the Director: ")); + + IO.println("When prompted, enter the value you wish to update." + + "\nIf you don't want to change it, leave the input blank."); + + String name = IO.readln("Enter the full name of the Director: "); + String country = IO.readln("Enter the country of the Director: "); + Integer birthYear = null; + Integer yearOfDeath = null; + try { + birthYear = Integer.valueOf(IO.readln("Enter the birth year of the Director: ")); + } catch (NumberFormatException _) { + } + try { + yearOfDeath = Integer.valueOf(IO.readln("Enter the year of death of the Director: ")); + } catch (NumberFormatException _) { + } + + Director updatedDirector = directorService.findDirectorId(id); + if(name != null && !name.isEmpty()) + updatedDirector.setName(name); + if(country != null && !country.isEmpty()) + updatedDirector.setCountry(country); + if(birthYear != null) + updatedDirector.setBirthYear(birthYear); + if(yearOfDeath != null) + updatedDirector.setYearOfDeath(yearOfDeath); + directorService.update(updatedDirector); + + } + + private void filmMenu() { + System.out.println(""" + You are in the Film Menu. + + Please select an action below: + + 1. Create new entry + 2. List entries + 3. List specific entry + 4. Update existing entry + + 5. Exit + + """); + switch (IO.readln()){ + case "1" -> createFilm(); + case "2" -> listFilms(); + case "3" -> listSpecificFilm(); + case "4" -> updateFilm(); + case "5" -> mainMenu(); + default -> invalidInput(); + } + } + + private void createFilm() { + String title = IO.readln("Enter the title of the Film: "); + + try { + Film film = new Film(); + film.setTitle(title); + film.setDirector(directorService.findDirectorId(Long.valueOf(IO.readln("Enter the ID of the Director: ")))); + filmService.create(film); + } catch (NumberFormatException e) { + System.out.println("Invalid input!"); + } + } + + private void listFilms() { + IO.println(filmService.findAll()); + } + + private void listSpecificFilm() { + String input = IO.readln("Enter the ID or title of the Film: "); + Film f; + try{ + f = filmService.findFilmId(Long.valueOf(input)); + } catch (NumberFormatException e) { + f = filmService.findFilmTitle(input); + } + + IO.println("Title: " + f.getTitle() + + "\nDirector: " + f.getDirector()); + } + + private void updateFilm() { + try { + IO.println("When prompted, enter the value you wish to update." + + "\nIf you don't want to change it, leave the input blank."); + Film film = filmService.findFilmId(Long.valueOf(IO.readln("Enter the ID of the Film: "))); + String title = IO.readln("Enter the title of the Film: "); + if(title != null && !title.isEmpty()) + film.setTitle(title); + try { + Director director = directorService.findDirectorId(Long.valueOf(IO.readln("Enter the ID of the Director: "))); + film.setDirector(director); + } catch (NumberFormatException _) { + } + + filmService.update(film); + } catch (NumberFormatException e) { + System.out.println("Invalid input!"); + } + } + + private void seriesMenu() { + System.out.println(""" + You are in the Series Menu. + + Please select an action below: + + 1. Create new entry + 2. List entries + 3. List specific entry + 4. Update existing entry + + 5. Exit + + """); + switch (IO.readln()){ + case "1" -> createSeries(); + case "2" -> listSeries(); + case "3" -> listSpecificSeries(); + case "4" -> updateSeries(); + case "5" -> mainMenu(); + default -> invalidInput(); + } + } + + private void createSeries() { + try { + String title = IO.readln("Enter the title of the Series: "); + int episodes = Integer.parseInt(IO.readln("Enter the number of episodes in the Series: ")); + int firstAired = Integer.parseInt(IO.readln("Enter the year the Series was first released: ")); + Integer lastAired = null; + try { + lastAired = Integer.valueOf(IO.readln("Enter the year the Series ended." + + "\nLeave blank if not yet finished: ")); + } catch (NumberFormatException _) { + } + String starActors = IO.readln("Enter the star actors of the Series: "); + + Series series = new Series(); + series.setTitle(title); + series.setEpisodes(episodes); + series.setFirstAired(firstAired); + series.setLastAired(lastAired); + series.setStarActors(starActors); + + seriesService.create(series); + + } catch (NumberFormatException e) { + System.out.println("Invalid input!"); + } + } + + private void listSeries() { + IO.println(seriesService.findAll()); + } + + private void listSpecificSeries() { + String title = IO.readln("Enter the ID or title of the Series: "); + Series s; + + try { + s = seriesService.findSeriesId(Long.valueOf(title)); + } catch (NumberFormatException e) { + s= seriesService.findSeriesTitle(title); + } + + IO.println("Title: " + s.getTitle() + + "\nDirector: " + s.getDirectors() + + "\nEpisodes: " + s.getEpisodes() + + "\nFirst Aired: " + s.getFirstAired() + + "\nLast Aired: " + s.getLastAired() + + "\nStar Actors: " + s.getStarActors()); + + } + + private void updateSeries() { + IO.println("When prompted, enter the value you wish to update." + + "\nIf you don't want to change it, leave the input blank."); + try { + Series series = seriesService.findSeriesId(Long.valueOf(IO.readln("Enter the ID of the Series: "))); + String title = IO.readln("Enter the title of the Series: "); + if (title != null && !title.isEmpty()) + series.setTitle(title); + try { + int episodes = Integer.parseInt(IO.readln("Enter the number of episodes in the Series: ")); + series.setEpisodes(episodes); + } catch (NumberFormatException _) { + } + try { + int firstAired = Integer.parseInt(IO.readln("Enter the year the Series was first released: ")); + series.setFirstAired(firstAired); + } catch (NumberFormatException _) { + } + try { + Integer lastAired = Integer.valueOf(IO.readln("Enter the year the Series ended: ")); + series.setLastAired(lastAired); + } catch (NumberFormatException _) { + } + String starActors = IO.readln("Enter the star actors of the Series: "); + if (starActors != null && !starActors.isEmpty()) + series.setStarActors(starActors); + + seriesService.update(series); + } catch (NumberFormatException e) { + System.out.println("Invalid input!"); + } + + } + +} diff --git a/src/main/java/org/example/Director.java b/src/main/java/org/example/Director.java new file mode 100644 index 00000000..a819decb --- /dev/null +++ b/src/main/java/org/example/Director.java @@ -0,0 +1,111 @@ +package org.example; + +import jakarta.persistence.*; + +import java.util.HashSet; +import java.util.Set; + +@Entity +public class Director extends BaseEntity{ + + + //private Long id; + + @OneToMany( + mappedBy = "director", + cascade = { CascadeType.PERSIST, CascadeType.MERGE }, + orphanRemoval = true + + ) + private Set films = new HashSet<>(); + + @ManyToMany( cascade = { CascadeType.PERSIST, CascadeType.MERGE }) + @JoinTable( + name = "director_series", + joinColumns = @JoinColumn(name = "directors_id"), + inverseJoinColumns = @JoinColumn(name = "series_id")) + + private Set series = new HashSet<>(); + + private String name; + + private String country; + + private Integer birthYear; + + + private Integer yearOfDeath; + + + + public Set getSeries() { + return series; + } + + public Set getFilms() { + return films; + } + + public void setFilms(Set films) { + this.films = films; + } + + public Integer getYearOfDeath() { + return yearOfDeath; + } + + public void setYearOfDeath(Integer yearOfDeath) { + this.yearOfDeath = yearOfDeath; + } + + public Integer getBirthYear() { + return birthYear; + } + + public void setBirthYear(Integer birthYear) { + this.birthYear = birthYear; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + + + public void addFilm(Film film) { + films.add(film); + film.setDirector(this); + + } + + public void removeFilm(Film film) { + films.remove(film); + film.setDirector(null); + } + + + + public void addSeries(Series s) { + series.add(s); + s.getDirectors().add(this); + } + public void removeSeries(Series s) { + s.getDirectors().remove(this); + series.remove(s); + } + + + +} diff --git a/src/main/java/org/example/DirectorDTO.java b/src/main/java/org/example/DirectorDTO.java new file mode 100644 index 00000000..544cfb91 --- /dev/null +++ b/src/main/java/org/example/DirectorDTO.java @@ -0,0 +1,17 @@ +package org.example; + + +import java.util.Set; + +public record DirectorDTO(String name, String country) { + public DirectorDTO(Director director) { + this(director.getName(), director.getCountry()); +// Long id; +// String name; +// String country; +// int birthYear; +// Integer yearOfDeath; +// Set filmIds; +// Set seriesIds; + } +} diff --git a/src/main/java/org/example/DirectorRepository.java b/src/main/java/org/example/DirectorRepository.java new file mode 100644 index 00000000..e91372a5 --- /dev/null +++ b/src/main/java/org/example/DirectorRepository.java @@ -0,0 +1,7 @@ +package org.example; + +import java.util.Optional; + +public interface DirectorRepository extends Repository { + Optional findByName(String name); +} diff --git a/src/main/java/org/example/DirectorRepositoryImpl.java b/src/main/java/org/example/DirectorRepositoryImpl.java new file mode 100644 index 00000000..c8f94eaf --- /dev/null +++ b/src/main/java/org/example/DirectorRepositoryImpl.java @@ -0,0 +1,27 @@ +package org.example; + +import jakarta.persistence.EntityManagerFactory; + +import java.util.Optional; + +//public class DirectorRepositoryImpl extends BaseRepositoryImpl implements DirectorRepository { + +public class DirectorRepositoryImpl extends BaseRepositoryImpl implements DirectorRepository { + private final EntityManagerFactory emf; + + public DirectorRepositoryImpl(EntityManagerFactory em) { + + //super(em.createEntityManager(), Director.class); + super(Director.class); + this.emf = em; + } + + @Override + public Optional findByName(String name) { + return em.createQuery("SELECT d FROM Director d WHERE d.name = :name", Director.class) + .setParameter("name", name) + .getResultStream() + .findFirst(); + + } +} diff --git a/src/main/java/org/example/DirectorService.java b/src/main/java/org/example/DirectorService.java new file mode 100644 index 00000000..84a08d54 --- /dev/null +++ b/src/main/java/org/example/DirectorService.java @@ -0,0 +1,81 @@ +package org.example; + + + +public class DirectorService { + + private final DirectorRepository directorRepository; + + public DirectorService(DirectorRepository directorRepository) { + this.directorRepository = directorRepository; + } + + + public Director create(Director director) { + return directorRepository.save(director); + } + + + public void addFilm(Long directorId, Film film) { + Director director = directorRepository.findById(directorId) + .orElseThrow(() -> new RuntimeException("Director not found: " + directorId)); + + director.addFilm(film); + directorRepository.save(director); + } + + public void update(Director director) { +// Director existingDirector = directorRepository.findById(id) +// .orElseThrow(() -> new RuntimeException("Director not found")); +// +// +// existingDirector.setYearOfDeath(director.getYearOfDeath()); +// existingDirector.setCountry(director.getCountry()); +// existingDirector.setBirthYear(director.getBirthYear()); +// existingDirector.setName(director.getName()); +// +// for (Film film : director.getFilms()) { +// existingDirector.addFilm(film); +// } + directorRepository.save(director); + } + + + public Iterable findAll() { + return directorRepository.findAll(); + + } + + + public void delete(Long id) { + Director director = directorRepository.findById(id) + .orElseThrow(() -> new RuntimeException("Director not found: " + id)); + + directorRepository.delete(director); + } + + public Director findDirectorId(Long id) { + //Old code +// Director director = (Director) directorRepository.findById(id) +// .orElseThrow(); +// +// return director; + //New code + return directorRepository.findById(id) + .orElseThrow(() -> new RuntimeException("Director not found: " + id)); + } + + public Director findDirectorName(String name) { + return directorRepository.findByName(name) + .orElseThrow(() -> new RuntimeException("Director not found: " + name)); + } +} + + + + + // public DirectorDTO find(Long id) { +// return directorRepository.findById(id) +// .map(d -> new DirectorDTO(d.getName(), d.getCountry())) +// .orElseThrow(() -> new RuntimeException("Director not found")); +// } diff --git a/src/main/java/org/example/Film.java b/src/main/java/org/example/Film.java new file mode 100644 index 00000000..9464a477 --- /dev/null +++ b/src/main/java/org/example/Film.java @@ -0,0 +1,57 @@ +package org.example; + +import jakarta.persistence.*; + +import org.example.Director; + +import java.util.Objects; + +@Entity +public class Film extends BaseEntity{ + + //private Long id; + + private String title; + @ManyToOne + + + private Director director; + + public Director getDirector() { + return director; + } + + public void setDirector(Director director) { + this.director = director; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + +// public void setId(Long id) { +// this.id = id; +// } +// +// public Long getId() { +// return id; +// } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Film)) return false; + Film other = (Film) o; + //return id != null && id.equals(other.id); + return getId() != null && getId().equals(other.getId()); + } + + @Override + public int hashCode() { + return 31; + } +} diff --git a/src/main/java/org/example/FilmDTO.java b/src/main/java/org/example/FilmDTO.java new file mode 100644 index 00000000..69e5ec54 --- /dev/null +++ b/src/main/java/org/example/FilmDTO.java @@ -0,0 +1,7 @@ +package org.example; + +public record FilmDTO(String title) { + public FilmDTO(Film film) { + this(film.getTitle()); + } +} diff --git a/src/main/java/org/example/FilmRepository.java b/src/main/java/org/example/FilmRepository.java new file mode 100644 index 00000000..d841949b --- /dev/null +++ b/src/main/java/org/example/FilmRepository.java @@ -0,0 +1,7 @@ +package org.example; + +import java.util.Optional; + +public interface FilmRepository extends Repository { + Optional findByTitle(String title); +} diff --git a/src/main/java/org/example/FilmRepositoryImpl.java b/src/main/java/org/example/FilmRepositoryImpl.java new file mode 100644 index 00000000..8933eff4 --- /dev/null +++ b/src/main/java/org/example/FilmRepositoryImpl.java @@ -0,0 +1,24 @@ +package org.example; + +import jakarta.persistence.EntityManagerFactory; + +import java.util.Optional; + +public class FilmRepositoryImpl extends BaseRepositoryImpl implements FilmRepository { + + private final EntityManagerFactory emf; + + public FilmRepositoryImpl(EntityManagerFactory em) { + super(Film.class); + this.emf = em; + } + + @Override + public Optional findByTitle(String title) { + return em.createQuery("SELECT f FROM Film f WHERE f.title = :title", Film.class) + .setParameter("title", title) + .getResultList().stream() + .findFirst(); + + } +} diff --git a/src/main/java/org/example/FilmService.java b/src/main/java/org/example/FilmService.java new file mode 100644 index 00000000..25084630 --- /dev/null +++ b/src/main/java/org/example/FilmService.java @@ -0,0 +1,33 @@ +package org.example; + +public class FilmService { + + private final FilmRepository filmRepository; + + public FilmService(FilmRepository filmRepository) { + this.filmRepository = filmRepository; + } + + public Film create(Film film) { + return filmRepository.save(film); + } + + public void update(Film film) { + filmRepository.save(film); + } + + public Iterable findAll() { + return filmRepository.findAll(); + + } + + public Film findFilmId(Long id) { + return filmRepository.findById(id) + .orElseThrow(() -> new RuntimeException("Film not found: " + id)); + } + + public Film findFilmTitle(String title) { + return filmRepository.findByTitle(title) + .orElseThrow(() -> new RuntimeException("Film not found: " + title)); + } +} diff --git a/src/main/java/org/example/Main.java b/src/main/java/org/example/Main.java new file mode 100644 index 00000000..ed2e5234 --- /dev/null +++ b/src/main/java/org/example/Main.java @@ -0,0 +1,42 @@ +package org.example; + +import jakarta.persistence.*; +import org.hibernate.jpa.HibernatePersistenceConfiguration; + +public class Main { + static void main() { + + + final PersistenceConfiguration cfg = new HibernatePersistenceConfiguration("emf") + .jdbcUrl("jdbc:mysql://localhost:3306/testdb") + .jdbcUsername("user") + .jdbcPassword("password") + .property("hibernate.hbm2ddl.auto", "update") + .property("hibernate.show_sql", "true") + .property("hibernate.format_sql", "true") + .property("hibernate.highlight_sql", "true") + .managedClasses(Film.class, Director.class, Series.class); + + try (EntityManagerFactory emf = cfg.createEntityManagerFactory()) { + emf.runInTransaction(em -> { + DirectorRepositoryImpl directorRepository = new DirectorRepositoryImpl(em); + if (!directorRepository.findAll().iterator().hasNext()) { + Director d = new Director(); + d.setName("John Doe"); + directorRepository.save(d); + } + }); + + DirectorRepositoryImpl directorRepository = new DirectorRepositoryImpl(em); + DirectorService directorService = new DirectorService(directorRepository); + + FilmRepositoryImpl filmRepository = new FilmRepositoryImpl(em); + FilmService filmService = new FilmService(filmRepository); + + SeriesRepositoryImpl seriesRepository = new SeriesRepositoryImpl(emf); + SeriesService seriesService = new SeriesService(seriesRepository); + + CLI cli = new CLI(); + cli.cliStart(directorService, filmService, seriesService); + } +} diff --git a/src/main/java/org/example/Repository.java b/src/main/java/org/example/Repository.java new file mode 100644 index 00000000..d006cd07 --- /dev/null +++ b/src/main/java/org/example/Repository.java @@ -0,0 +1,18 @@ +package org.example; + +import java.util.Optional; + +public interface Repository { + T save(T entity); + Optional findById(Long id); + void delete(T entity); + void deleteById(Long id); + Iterable findAll(); + boolean existsById(Long id); + + long count(); + + void flush(); + + void clear(); +} diff --git a/src/main/java/org/example/Series.java b/src/main/java/org/example/Series.java new file mode 100644 index 00000000..93f248e6 --- /dev/null +++ b/src/main/java/org/example/Series.java @@ -0,0 +1,88 @@ +package org.example; + +import jakarta.persistence.*; + +import java.util.HashSet; +import java.util.Set; + +@Entity +public class Series extends BaseEntity{ + + @ManyToMany(mappedBy = "series", cascade = { CascadeType.PERSIST, CascadeType.MERGE}) + private Set directors = new HashSet<>(); + + private String title; + private int episodes; + private int firstAired; + private Integer lastAired; + private String starActors; + + + + public void setTitle(String title) { + + this.title = title; + } + + public void setDirectors(Set directors) { + + this.directors = directors; + } + + public void setEpisodes(int episodes) { + + this.episodes = episodes; + } + + public void setFirstAired(int firstAired) { + + this.firstAired = firstAired; + } + + public void setLastAired(Integer lastAired) { + + this.lastAired = lastAired; + } + + public void setStarActors(String starActors) { + + this.starActors = starActors; + } + + public String getTitle() { + return title; + } + + public Set getDirectors() { + return directors; + } + + public int getEpisodes() { + return episodes; + } + + public int getFirstAired() { + return firstAired; + } + + public Integer getLastAired() { + return lastAired; + } + + public String getStarActors() { + return starActors; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Series)) return false; + Series other = (Series) o; + return getId() != null && getId().equals(other.getId()); + } + + @Override + public int hashCode() { + return 31; + } +} diff --git a/src/main/java/org/example/SeriesDTO.java b/src/main/java/org/example/SeriesDTO.java new file mode 100644 index 00000000..1a44c4b0 --- /dev/null +++ b/src/main/java/org/example/SeriesDTO.java @@ -0,0 +1,11 @@ +package org.example; + +public record SeriesDTO(String title, int episodes, int firstAired, Integer lastAired, String starActors){ + public SeriesDTO(Series series) { + this(series.getTitle(), + series.getEpisodes(), + series.getFirstAired(), + series.getLastAired(), + series.getStarActors()); + } +} diff --git a/src/main/java/org/example/SeriesRepository.java b/src/main/java/org/example/SeriesRepository.java new file mode 100644 index 00000000..5ff45a84 --- /dev/null +++ b/src/main/java/org/example/SeriesRepository.java @@ -0,0 +1,7 @@ +package org.example; + +import java.util.Optional; + +public interface SeriesRepository extends Repository { + Optional findByTitle(String title); +} diff --git a/src/main/java/org/example/SeriesRepositoryImpl.java b/src/main/java/org/example/SeriesRepositoryImpl.java new file mode 100644 index 00000000..aea28463 --- /dev/null +++ b/src/main/java/org/example/SeriesRepositoryImpl.java @@ -0,0 +1,23 @@ +package org.example; + +import jakarta.persistence.EntityManagerFactory; + +import java.util.Optional; + +public class SeriesRepositoryImpl extends BaseRepositoryImpl implements SeriesRepository { + + private final EntityManagerFactory emf; + + public SeriesRepositoryImpl(EntityManagerFactory em) { + super(Series.class); + this.emf = em; + } + + @Override + public Optional findByTitle(String title){ + return em.createQuery("SELECT s FROM Series s WHERE s.title = :title", Series.class) + .setParameter("title", title) + .getResultStream() + .findFirst(); + } +} diff --git a/src/main/java/org/example/SeriesService.java b/src/main/java/org/example/SeriesService.java new file mode 100644 index 00000000..93784fa8 --- /dev/null +++ b/src/main/java/org/example/SeriesService.java @@ -0,0 +1,40 @@ +package org.example; + +public class SeriesService { + + private final SeriesRepository seriesRepository; + + public SeriesService(SeriesRepository seriesRepository) { + this.seriesRepository = seriesRepository; + } + + public Series create(Series series) { + return seriesRepository.save(series); + } + +// public void addSeries(Long directorId, Series series) { +// Director director = directorRepository.findById(directorId) +// .orElseThrow(() -> new RuntimeException("Director not found: " + directorId)); +// +// director.addSeries(series); +// directorRepository.save(director); +// } + public void update(Series series) { + seriesRepository.save(series); + } + + public Iterable findAll() { + return seriesRepository.findAll(); + + } + + public Series findSeriesId(Long id) { + return seriesRepository.findById(id) + .orElseThrow(() -> new RuntimeException("Series not found: " + id)); + } + + public Series findSeriesTitle(String title) { + return seriesRepository.findByTitle(title) + .orElseThrow(() -> new RuntimeException("Series not found: " + title)); + } +} diff --git a/src/main/resources/META-INF/persistence.xml b/src/main/resources/META-INF/persistence.xml new file mode 100644 index 00000000..fdd34a29 --- /dev/null +++ b/src/main/resources/META-INF/persistence.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + +