From cd5855350223bc6240d112acfe9c6ed2760c65a5 Mon Sep 17 00:00:00 2001 From: "github-classroom[bot]" <66690702+github-classroom[bot]@users.noreply.github.com> Date: Mon, 15 Dec 2025 09:57:05 +0000 Subject: [PATCH 01/41] add deadline --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5150e50f..05def9a9 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. From f043eb4c25aeb91357754a7f20fb7a85af8b1a4e Mon Sep 17 00:00:00 2001 From: Linnea Vardal Date: Tue, 16 Dec 2025 10:00:21 +0100 Subject: [PATCH 02/41] Add Main and Film class. Add persistenceconfiguration in Main. Add Entity in Film. Co-authored-by: Mattias Barth mattias.barth@gmail.com EdvinSandgren 229709012+EdvinSandgren@users.noreply.github.com johanhiths Johan.hietala@iths.se --- src/main/java/Film.java | 40 ++++++++++++++++++++++++++++++++++++++++ src/main/java/Main.java | 23 +++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 src/main/java/Film.java create mode 100644 src/main/java/Main.java diff --git a/src/main/java/Film.java b/src/main/java/Film.java new file mode 100644 index 00000000..82eb775d --- /dev/null +++ b/src/main/java/Film.java @@ -0,0 +1,40 @@ +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; + +@Entity +public class Film { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + String title; + String director; + + public String getDirector() { + return director; + } + + public void setDirector(String 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; + } + + +} diff --git a/src/main/java/Main.java b/src/main/java/Main.java new file mode 100644 index 00000000..5b7b0822 --- /dev/null +++ b/src/main/java/Main.java @@ -0,0 +1,23 @@ +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.PersistenceConfiguration; +import org.hibernate.jpa.HibernatePersistenceConfiguration; + +import java.util.List; + +public class Main { + static void main() { + + + final PersistenceConfiguration cfg = new HibernatePersistenceConfiguration("emf") + .jdbcUrl("jdbc:mysql://localhost:3306/jpa") + .jdbcUsername("root") + .jdbcPassword("root") + .property("hibernate.hbm2ddl.auto", "update") + .property("hibernate.show_sql", "true") + .property("hibernate.format_sql", "true") + .property("hibernate.highlight_sql", "true") + .managedClasses(); + + +} +} From 86c2ac25f05b24abc12df9276ff782701d0f9a68 Mon Sep 17 00:00:00 2001 From: Linnea Vardal Date: Tue, 16 Dec 2025 10:51:43 +0100 Subject: [PATCH 03/41] Add Director Class with getters and setters. Co-authored-by: Mattias Barth mattias.barth@gmail.com EdvinSandgren 229709012+EdvinSandgren@users.noreply.github.com johanhiths Johan.hietala@iths.se --- src/main/java/Director.java | 60 +++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/main/java/Director.java diff --git a/src/main/java/Director.java b/src/main/java/Director.java new file mode 100644 index 00000000..6c05171c --- /dev/null +++ b/src/main/java/Director.java @@ -0,0 +1,60 @@ +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; + +@Entity +public class Director { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + String name; + String country; + int birthYear; + int yearOfDeath; + + public int getYearOfDeath() { + return yearOfDeath; + } + + public void setYearOfDeath(int yearOfDeath) { + this.yearOfDeath = yearOfDeath; + } + + public int getBirthYear() { + return birthYear; + } + + public void setBirthYear(int 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 setId(Long id) { + this.id = id; + } + + public Long getId() { + return id; + } + + +} + + From 5c33218e5d96b7f918cf4b9a6a12be06b63b4997 Mon Sep 17 00:00:00 2001 From: Linnea Vardal Date: Tue, 16 Dec 2025 13:13:59 +0100 Subject: [PATCH 04/41] Add entity manager to Main. Co-authored-by: Mattias Barth mattias.barth@gmail.com EdvinSandgren 229709012+EdvinSandgren@users.noreply.github.com johanhiths Johan.hietala@iths.se --- src/main/java/Main.java | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 5b7b0822..d0b5b088 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -1,23 +1,42 @@ +import jakarta.persistence.Entity; import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.Persistence; import jakarta.persistence.PersistenceConfiguration; import org.hibernate.jpa.HibernatePersistenceConfiguration; import java.util.List; public class Main { - static void main() { + public static void main(String[] args) { final PersistenceConfiguration cfg = new HibernatePersistenceConfiguration("emf") - .jdbcUrl("jdbc:mysql://localhost:3306/jpa") + .jdbcUrl("jdbc:mysql://localhost:3306/film_database") .jdbcUsername("root") .jdbcPassword("root") .property("hibernate.hbm2ddl.auto", "update") .property("hibernate.show_sql", "true") .property("hibernate.format_sql", "true") .property("hibernate.highlight_sql", "true") - .managedClasses(); + .managedClasses(Film.class, Director.class); + try (EntityManagerFactory emf = cfg.createEntityManagerFactory()) { + emf.runInTransaction(em -> { + //If no Organizations in database, add some + if (em.createQuery("select count(o) from Film o", Long.class) + .getSingleResult() == 0) { + Film film1 = new Film(); + em.persist(film1); + em.flush(); + Film film2 = new Film(); + em.persist(film2); + } + System.out.println("==== Using select query, N + 1 ===="); + em.createQuery("from Film", Film.class) + .getResultList().forEach(System.out::println); + }); -} + } + + } } From c5b0d5ff43f68f3e1be2aaa8625744dae4dd8fbf Mon Sep 17 00:00:00 2001 From: Linnea Vardal Date: Tue, 16 Dec 2025 14:00:01 +0100 Subject: [PATCH 05/41] Add OneToMany in Director Class. Add ManyToOne in Film Class. Co-authored-by: Mattias Barth mattias.barth@gmail.com EdvinSandgren 229709012+EdvinSandgren@users.noreply.github.com johanhiths Johan.hietala@iths.se --- src/main/java/Director.java | 13 +++++++++---- src/main/java/Film.java | 12 +++++------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/main/java/Director.java b/src/main/java/Director.java index 6c05171c..db0ca147 100644 --- a/src/main/java/Director.java +++ b/src/main/java/Director.java @@ -1,14 +1,19 @@ -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; +import jakarta.persistence.*; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; @Entity public class Director { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + @OneToMany(mappedBy = "director") + private Set film = new HashSet<>(); + String name; String country; int birthYear; diff --git a/src/main/java/Film.java b/src/main/java/Film.java index 82eb775d..94bf19dd 100644 --- a/src/main/java/Film.java +++ b/src/main/java/Film.java @@ -1,7 +1,4 @@ -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; +import jakarta.persistence.*; @Entity public class Film { @@ -10,13 +7,14 @@ public class Film { private Long id; String title; - String director; + @ManyToOne + Director director; - public String getDirector() { + public Director getDirector() { return director; } - public void setDirector(String director) { + public void setDirector(Director director) { this.director = director; } From 3f3262f65223d1016cba98e2c77abab1393c1279 Mon Sep 17 00:00:00 2001 From: Linnea Vardal Date: Tue, 16 Dec 2025 14:25:25 +0100 Subject: [PATCH 06/41] Made yearOfDeath nullable. Co-authored-by: Mattias Barth mattias.barth@gmail.com EdvinSandgren 229709012+EdvinSandgren@users.noreply.github.com johanhiths Johan.hietala@iths.se --- src/main/java/Director.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/Director.java b/src/main/java/Director.java index db0ca147..f269f52c 100644 --- a/src/main/java/Director.java +++ b/src/main/java/Director.java @@ -17,6 +17,7 @@ public class Director { String name; String country; int birthYear; + @Column(nullable = true) int yearOfDeath; public int getYearOfDeath() { From 5125f3acb9cb3017cb933123eb38bea74c9c2362 Mon Sep 17 00:00:00 2001 From: Linnea Vardal Date: Wed, 17 Dec 2025 09:20:34 +0100 Subject: [PATCH 07/41] Fixed issues according to Coderabbit. Co-authored-by: Mattias Barth mattias.barth@gmail.com EdvinSandgren 229709012+EdvinSandgren@users.noreply.github.com johanhiths Johan.hietala@iths.se --- src/main/java/Director.java | 24 +++++++++++++++++------- src/main/java/Film.java | 5 +++-- src/main/java/Main.java | 2 +- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/main/java/Director.java b/src/main/java/Director.java index f269f52c..f34554c3 100644 --- a/src/main/java/Director.java +++ b/src/main/java/Director.java @@ -12,19 +12,29 @@ public class Director { private Long id; @OneToMany(mappedBy = "director") - private Set film = new HashSet<>(); + private Set films = new HashSet<>(); - String name; - String country; - int birthYear; + private String name; + private String country; + private int birthYear; @Column(nullable = true) - int yearOfDeath; + private Integer yearOfDeath; - public int getYearOfDeath() { + + + public Set getFilms() { + return films; + } + + public void setFilms(Set films) { + this.films = films; + } + + public Integer getYearOfDeath() { return yearOfDeath; } - public void setYearOfDeath(int yearOfDeath) { + public void setYearOfDeath(Integer yearOfDeath) { this.yearOfDeath = yearOfDeath; } diff --git a/src/main/java/Film.java b/src/main/java/Film.java index 94bf19dd..6beaac82 100644 --- a/src/main/java/Film.java +++ b/src/main/java/Film.java @@ -6,9 +6,10 @@ public class Film { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - String title; + private String title; @ManyToOne - Director director; + @JoinColumn(name = "director_id") + private Director director; public Director getDirector() { return director; diff --git a/src/main/java/Main.java b/src/main/java/Main.java index d0b5b088..d6254896 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -21,7 +21,7 @@ public static void main(String[] args) { .managedClasses(Film.class, Director.class); try (EntityManagerFactory emf = cfg.createEntityManagerFactory()) { emf.runInTransaction(em -> { - //If no Organizations in database, add some + //If no Films in database, add some if (em.createQuery("select count(o) from Film o", Long.class) .getSingleResult() == 0) { Film film1 = new Film(); From 4d51d1f85dfee82b44f19edab07893c62bb4fddf Mon Sep 17 00:00:00 2001 From: Mattias Barth <3858736+mattiasbarth@users.noreply.github.com> Date: Thu, 18 Dec 2025 11:27:19 +0100 Subject: [PATCH 08/41] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 05def9a9..2ab82cb2 100644 --- a/README.md +++ b/README.md @@ -10,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 From be0e7b44323d4d7fcbbfb0a6f2adf2ecf2d06d91 Mon Sep 17 00:00:00 2001 From: Edvin Sandgren <229709012+EdvinSandgren@users.noreply.github.com> Date: Wed, 7 Jan 2026 14:15:16 +0100 Subject: [PATCH 09/41] Adds the basic framework for the CLI, printing menus based on the user's input. --- src/main/java/CLI.java | 123 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 src/main/java/CLI.java diff --git a/src/main/java/CLI.java b/src/main/java/CLI.java new file mode 100644 index 00000000..e7239a47 --- /dev/null +++ b/src/main/java/CLI.java @@ -0,0 +1,123 @@ +public class CLI { + + void mainMenu(){ + System.out.println(""" + Welcome to the Film Database! + + Please select a category to view below: + + 1. Directors + 2. Films + 3. Series + + 4. Exit + + """); + switch (System.console().readLine()){ + 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!" + + "PLease 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. Update existing entry + + 4. Exit + + """); + switch (System.console().readLine()){ + case "1" -> createDirector(); + case "2" -> listDirectors(); + case "3" -> updateDirector(); + case "4" -> mainMenu(); + default -> invalidInput(); + } + } + + private void createDirector() { + } + + private void listDirectors() { + } + + private void updateDirector() { + } + + 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. Update existing entry + + 4. Exit + + """); + switch (System.console().readLine()){ + case "1" -> createFilm(); + case "2" -> listFilms(); + case "3" -> updateFilm(); + case "4" -> mainMenu(); + default -> invalidInput(); + } + } + + private void createFilm() { + } + + private void listFilms() { + } + + private void updateFilm() { + } + + 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. Update existing entry + + 4. Exit + + """); + switch (System.console().readLine()){ + case "1" -> createSeries(); + case "2" -> listSeries(); + case "3" -> updateSeries(); + case "4" -> mainMenu(); + default -> invalidInput(); + } + } + + private void createSeries() { + } + + private void listSeries() { + } + + private void updateSeries() { + } + +} From 5427500e5f837193ea58e03ec2ea24e6aaf3cbb1 Mon Sep 17 00:00:00 2001 From: JohanHiths Date: Wed, 7 Jan 2026 14:48:37 +0100 Subject: [PATCH 10/41] Add files via upload Crud operations --- src/main/java/org/example/BaseEntity.java | 19 +++ .../java/org/example/BaseRepositoryImpl.java | 85 ++++++++++++ src/main/java/org/example/Director.java | 127 ++++++++++++++++++ src/main/java/org/example/DirectorDTO.java | 17 +++ .../java/org/example/DirectorRepository.java | 7 + .../org/example/DirectorRepositoryImpl.java | 23 ++++ .../java/org/example/DirectorService.java | 48 +++++++ src/main/java/org/example/Repository.java | 18 +++ 8 files changed, 344 insertions(+) create mode 100644 src/main/java/org/example/BaseEntity.java create mode 100644 src/main/java/org/example/BaseRepositoryImpl.java create mode 100644 src/main/java/org/example/Director.java create mode 100644 src/main/java/org/example/DirectorDTO.java create mode 100644 src/main/java/org/example/DirectorRepository.java create mode 100644 src/main/java/org/example/DirectorRepositoryImpl.java create mode 100644 src/main/java/org/example/DirectorService.java create mode 100644 src/main/java/org/example/Repository.java 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..41ba4879 --- /dev/null +++ b/src/main/java/org/example/BaseRepositoryImpl.java @@ -0,0 +1,85 @@ +package org.example; + +import jakarta.persistence.EntityManager; + +import java.util.Optional; + +public class BaseRepositoryImpl implements Repository{ + + protected EntityManager em; + protected Class entityClass; + + + public BaseRepositoryImpl(EntityManager em, Class entityClass) { + this.em = em; + this.entityClass = entityClass; + } + + + public T save(T entity) { + 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.getName() + " e", entityClass + ).getResultList(); + } + + @Override + public boolean existsById(Long id) { + Long count = em.createQuery( + "select count(e) from " + entityClass.getName() + " 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.getName() + " e", Long.class).getSingleResult(); + } + + @Override + public void flush() { + em.flush(); + } + + @Override + public void clear() { + em.clear(); + } + +} diff --git a/src/main/java/org/example/Director.java b/src/main/java/org/example/Director.java new file mode 100644 index 00000000..1674b2c4 --- /dev/null +++ b/src/main/java/org/example/Director.java @@ -0,0 +1,127 @@ +package org.example; + +import jakarta.persistence.*; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import java.util.HashSet; +import java.util.Set; + +@Entity +public class Director extends BaseEntity{ + + + private Long id; + + @OneToMany( + mappedBy = "director", + cascade = CascadeType.PERSIST, + orphanRemoval = true + + ) + private Set films = new HashSet<>(); + + @ManyToMany() + private Set series = new HashSet<>(); + + @NotBlank + @Size(max = 100) + private String name; + + @NotBlank + private String country; + + @Min(1850) + private int birthYear; + + @Column(nullable = true) + @Max(2100) + private Integer yearOfDeath; + + + + 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 int getBirthYear() { + return birthYear; + } + + public void setBirthYear(int 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 setId(Long id) { + + this.id = id; + } + + 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); + } + + public Long getId() { + return id; + } + +// @Override +// public boolean equals(Object o) { +// if (this == o) return true; +// if (!(o instanceof Director)) return false; +// Director other = (Director) o; +// return id != null && id.equals(other.id); +// } +// @Override +// public int hashCode() { +// return 31; +// } +} diff --git a/src/main/java/org/example/DirectorDTO.java b/src/main/java/org/example/DirectorDTO.java new file mode 100644 index 00000000..748c0434 --- /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..04531991 --- /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..200d32b5 --- /dev/null +++ b/src/main/java/org/example/DirectorRepositoryImpl.java @@ -0,0 +1,23 @@ +package org.example; + +import jakarta.persistence.EntityManager; + +import java.util.Optional; + +public class DirectorRepositoryImpl extends BaseRepositoryImpl implements DirectorRepository { + + public DirectorRepositoryImpl(EntityManager em) { + super(em, Director.class); + } + + @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..17180857 --- /dev/null +++ b/src/main/java/org/example/DirectorService.java @@ -0,0 +1,48 @@ +package org.example; + +import jakarta.transaction.Transactional; + +public class DirectorService { + + private final DirectorRepository directorRepository; + + public DirectorService(DirectorRepository directorRepository, FilmRepository filmRepo) { + this.directorRepository = directorRepository; + } + + @Transactional + public Director create(Director director) { + return (Director) directorRepository.save(director); + } + + @Transactional + public void addFilm(Long directorId, Film film) { + Director director = (Director) directorRepository.findById(directorId) + .orElseThrow(); + + director.addFilm(film); + } + + @Transactional + public DirectorDTO find(Long id) { + return directorRepository.findById(id) + .map(d -> new DirectorDTO(d.getName(), d.getCountry())) + .orElseThrow(() -> new RuntimeException("Director not found")); + } + + @Transactional + public void delete(Long id) { + Director director = (Director) directorRepository.findById(id) + .orElseThrow(); + + directorRepository.delete(director); + } + @Transactional + public Director findDirector(Long id) { + Director director = (Director) directorRepository.findById(id) + .orElseThrow(); + + return director; + + } +} 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(); +} From 0135fb8ff9e2279d317772c8791a71ebac817e9d Mon Sep 17 00:00:00 2001 From: Edvin Sandgren <229709012+EdvinSandgren@users.noreply.github.com> Date: Thu, 8 Jan 2026 02:26:13 +0100 Subject: [PATCH 11/41] Adds the basic interface for the CRUD operations. --- src/main/java/CLI.java | 171 +++++++++++++++++++++++++++++++---------- 1 file changed, 131 insertions(+), 40 deletions(-) diff --git a/src/main/java/CLI.java b/src/main/java/CLI.java index e7239a47..d227b66e 100644 --- a/src/main/java/CLI.java +++ b/src/main/java/CLI.java @@ -1,24 +1,34 @@ -public class CLI { - - void mainMenu(){ - System.out.println(""" - Welcome to the Film Database! +import jakarta.persistence.EntityManager; - Please select a category to view below: +import java.io.IOException; - 1. Directors - 2. Films - 3. Series - - 4. Exit - - """); - switch (System.console().readLine()){ - case "1" -> directorMenu(); - case "2" -> filmMenu(); - case "3" -> seriesMenu(); - case "4" -> System.exit(0); - default -> invalidInput(); +public class CLI { + private final String os = System.getProperty("os.name"); + EntityManager em; + + void mainMenu(EntityManager entityManager) { //throws IOException, InterruptedException { + while(true) { + //clearConsole(); + em = entityManager; + 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(); + } } } @@ -27,7 +37,8 @@ private static void invalidInput() { "PLease enter the number of the option you wish to choose"); } - private void directorMenu() { + private void directorMenu() { //throws IOException, InterruptedException { + //clearConsole(); System.out.println(""" You are in the Director Menu. @@ -35,30 +46,58 @@ private void directorMenu() { 1. Create new entry 2. List entries - 3. Update existing entry + 3. List specific entry + 4. Update existing entry - 4. Exit + 5. Exit """); - switch (System.console().readLine()){ + switch (IO.readln()){ case "1" -> createDirector(); case "2" -> listDirectors(); - case "3" -> updateDirector(); - case "4" -> mainMenu(); + case "3" -> listSpecificDirector(); + case "4" -> updateDirector(); + case "5" -> mainMenu(em); default -> invalidInput(); } } - private void createDirector() { + private void createDirector() { //throws IOException, InterruptedException { + //clearConsole(); + String name = IO.readln("Enter the full name of the Director: "); + String country = IO.readln("Enter the country of the Director: "); + int birthYear = Integer.parseInt(IO.readln("Enter the birth year of the Director: ")); + Integer yearOfDeath = Integer.valueOf(IO.readln("Enter the year of death of the Director." + + "If they're alive, leave blank: ")); + + //TODO: + //send information to create-method in Director class } private void listDirectors() { + IO.println(Director.findAll(em)); + } + + private void listSpecificDirector() { + String name = IO.readln("Enter the name of the Director: "); + IO.println(Director.findByName(em, name)); } private void updateDirector() { + IO.println("When prompted, enter the value you wish to update." + + "If 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 = Integer.valueOf(IO.readln("Enter the birth year of the Director: ")); + Integer yearOfDeath = Integer.valueOf(IO.readln("Enter the year of death of the Director: ")); + + //TODO: + //Determine which values aren't null, and update them } - private void filmMenu() { + private void filmMenu() { //throws IOException, InterruptedException { + //clearConsole(); System.out.println(""" You are in the Film Menu. @@ -66,30 +105,46 @@ private void filmMenu() { 1. Create new entry 2. List entries - 3. Update existing entry + 3. List specific entry + 4. Update existing entry - 4. Exit + 5. Exit """); - switch (System.console().readLine()){ + switch (IO.readln()){ case "1" -> createFilm(); case "2" -> listFilms(); - case "3" -> updateFilm(); - case "4" -> mainMenu(); + case "3" -> listSpecificFilm(); + case "4" -> updateFilm(); + case "5" -> mainMenu(em); default -> invalidInput(); } } - private void createFilm() { + private void createFilm() { //throws IOException, InterruptedException { + //clearConsole(); + String title = IO.readln("Enter the title of the Film: "); + + //TODO: + //send information to create-method in Film class } private void listFilms() { + IO.println(Film.findAll(em)); + } + + private void listSpecificFilm() { + String title = IO.readln("Enter the title of the Film: "); + IO.println(Film.findByName(em, title)); } private void updateFilm() { + String title = IO.readln("Enter the title of the Film: "); + Film.update(em, title); } - private void seriesMenu() { + private void seriesMenu() { //throws IOException, InterruptedException { + //clearConsole(); System.out.println(""" You are in the Series Menu. @@ -97,27 +152,63 @@ private void seriesMenu() { 1. Create new entry 2. List entries - 3. Update existing entry + 3. List specific entry + 4. Update existing entry - 4. Exit + 5. Exit """); - switch (System.console().readLine()){ + switch (IO.readln()){ case "1" -> createSeries(); case "2" -> listSeries(); - case "3" -> updateSeries(); - case "4" -> mainMenu(); + case "3" -> listSpecificSeries(); + case "4" -> updateSeries(); + case "5" -> mainMenu(em); default -> invalidInput(); } } - private void createSeries() { + private void createSeries() { //throws IOException, InterruptedException { + //clearConsole(); + 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 = Integer.valueOf(IO.readln("Enter the year the Series ended." + + "leave blank if not yet finished: ")); + String starActors = IO.readln("Enter the star actors of the Series: "); + + //TODO: + //send information to create-method in Series class } private void listSeries() { + IO.println(Series.findAll(em)); + } + + private void listSpecificSeries() { + String title = IO.readln("Enter the title of the Series: "); + IO.println(Series.findByName(em, title)); } private void updateSeries() { + IO.println("When prompted, enter the value you wish to update." + + "If you don't want to change it, leave the input blank."); + + String title = IO.readln("Enter the title of the Series: "); + Integer episodes = Integer.valueOf(IO.readln("Enter the number of episodes in the Series: ")); + Integer firstAired = Integer.valueOf(IO.readln("Enter the year the Series was first released: ")); + Integer lastAired = Integer.valueOf(IO.readln("Enter the year the Series ended: ")); + String starActors = IO.readln("Enter the star actors of the Series: "); + + //TODO: + //Determine which values aren't null, and update them } +// private void clearConsole() throws IOException, InterruptedException { +// if(os.contains("Windows")) +// new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor(); +// else +// new ProcessBuilder("clear").inheritIO().start().waitFor(); +// } + } From cc6a16efe952c483a85717a69973c0360d6a70e5 Mon Sep 17 00:00:00 2001 From: JohanHiths Date: Thu, 8 Jan 2026 09:28:55 +0100 Subject: [PATCH 12/41] Add files via upload --- src/main/java/org/example/Director.java | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/example/Director.java b/src/main/java/org/example/Director.java index 1674b2c4..89c254d2 100644 --- a/src/main/java/org/example/Director.java +++ b/src/main/java/org/example/Director.java @@ -113,15 +113,15 @@ public Long getId() { return id; } -// @Override -// public boolean equals(Object o) { -// if (this == o) return true; -// if (!(o instanceof Director)) return false; -// Director other = (Director) o; -// return id != null && id.equals(other.id); -// } -// @Override -// public int hashCode() { -// return 31; -// } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Director)) return false; + Director other = (Director) o; + return id != null && id.equals(other.id); + } + @Override + public int hashCode() { + return 31; + } } From 719fa14dd9866b5aa3465f4822b7fb5fece71bda Mon Sep 17 00:00:00 2001 From: JohanHiths Date: Thu, 8 Jan 2026 10:48:46 +0100 Subject: [PATCH 13/41] Add files via upload --- .../java/org/example/DirectorRepositoryImpl.java | 6 ++++-- src/main/java/org/example/DirectorService.java | 12 ++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/example/DirectorRepositoryImpl.java b/src/main/java/org/example/DirectorRepositoryImpl.java index 200d32b5..659d096c 100644 --- a/src/main/java/org/example/DirectorRepositoryImpl.java +++ b/src/main/java/org/example/DirectorRepositoryImpl.java @@ -1,13 +1,15 @@ package org.example; import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; import java.util.Optional; public class DirectorRepositoryImpl extends BaseRepositoryImpl implements DirectorRepository { - public DirectorRepositoryImpl(EntityManager em) { - super(em, Director.class); + public DirectorRepositoryImpl(EntityManagerFactory em) { + + super(em.createEntityManager(), Director.class); } @Override diff --git a/src/main/java/org/example/DirectorService.java b/src/main/java/org/example/DirectorService.java index 17180857..899cd4f5 100644 --- a/src/main/java/org/example/DirectorService.java +++ b/src/main/java/org/example/DirectorService.java @@ -1,6 +1,6 @@ package org.example; -import jakarta.transaction.Transactional; + public class DirectorService { @@ -10,12 +10,12 @@ public DirectorService(DirectorRepository directorRepository, FilmRepository fil this.directorRepository = directorRepository; } - @Transactional + public Director create(Director director) { return (Director) directorRepository.save(director); } - @Transactional + public void addFilm(Long directorId, Film film) { Director director = (Director) directorRepository.findById(directorId) .orElseThrow(); @@ -23,21 +23,21 @@ public void addFilm(Long directorId, Film film) { director.addFilm(film); } - @Transactional + public DirectorDTO find(Long id) { return directorRepository.findById(id) .map(d -> new DirectorDTO(d.getName(), d.getCountry())) .orElseThrow(() -> new RuntimeException("Director not found")); } - @Transactional + public void delete(Long id) { Director director = (Director) directorRepository.findById(id) .orElseThrow(); directorRepository.delete(director); } - @Transactional + public Director findDirector(Long id) { Director director = (Director) directorRepository.findById(id) .orElseThrow(); From 27cc14bf9fd9a2bc51c9c2d4921f68e058abcf59 Mon Sep 17 00:00:00 2001 From: JohanHiths Date: Thu, 8 Jan 2026 11:20:33 +0100 Subject: [PATCH 14/41] Add files via upload --- .../java/org/example/BaseRepositoryImpl.java | 21 ++-- src/main/java/org/example/Director.java | 8 +- src/main/java/org/example/DirectorDTO.java | 14 +-- .../java/org/example/DirectorService.java | 9 +- src/main/java/org/example/Film.java | 67 +++++++++++ src/main/java/org/example/Main.java | 50 +++++++++ src/main/java/org/example/Series.java | 105 ++++++++++++++++++ src/main/resources/META-INF/persistence.xml | 22 ++++ 8 files changed, 273 insertions(+), 23 deletions(-) create mode 100644 src/main/java/org/example/Film.java create mode 100644 src/main/java/org/example/Main.java create mode 100644 src/main/java/org/example/Series.java create mode 100644 src/main/resources/META-INF/persistence.xml diff --git a/src/main/java/org/example/BaseRepositoryImpl.java b/src/main/java/org/example/BaseRepositoryImpl.java index 41ba4879..f25591ac 100644 --- a/src/main/java/org/example/BaseRepositoryImpl.java +++ b/src/main/java/org/example/BaseRepositoryImpl.java @@ -4,7 +4,7 @@ import java.util.Optional; -public class BaseRepositoryImpl implements Repository{ +public class BaseRepositoryImpl implements Repository { protected EntityManager em; protected Class entityClass; @@ -17,15 +17,20 @@ public BaseRepositoryImpl(EntityManager em, Class entityClass) { public T save(T entity) { - if (entity.getId() == null) { - em.persist(entity); + if (entity == null) { - return entity; - } - else{ - return em.merge(entity); + 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; @@ -52,7 +57,7 @@ public void deleteById(Long id) { @Override public Iterable findAll() { return em.createQuery( - "select e from " + entityClass.getName() + " e", entityClass + "select e from " + entityClass.getSimpleName() + " e", entityClass ).getResultList(); } diff --git a/src/main/java/org/example/Director.java b/src/main/java/org/example/Director.java index 89c254d2..da0ac69a 100644 --- a/src/main/java/org/example/Director.java +++ b/src/main/java/org/example/Director.java @@ -2,10 +2,10 @@ import jakarta.persistence.*; -import javax.validation.constraints.Max; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; import java.util.HashSet; import java.util.Set; diff --git a/src/main/java/org/example/DirectorDTO.java b/src/main/java/org/example/DirectorDTO.java index 748c0434..544cfb91 100644 --- a/src/main/java/org/example/DirectorDTO.java +++ b/src/main/java/org/example/DirectorDTO.java @@ -6,12 +6,12 @@ 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; +// Long id; +// String name; +// String country; +// int birthYear; +// Integer yearOfDeath; +// Set filmIds; +// Set seriesIds; } } diff --git a/src/main/java/org/example/DirectorService.java b/src/main/java/org/example/DirectorService.java index 899cd4f5..77343fe1 100644 --- a/src/main/java/org/example/DirectorService.java +++ b/src/main/java/org/example/DirectorService.java @@ -6,21 +6,22 @@ public class DirectorService { private final DirectorRepository directorRepository; - public DirectorService(DirectorRepository directorRepository, FilmRepository filmRepo) { + public DirectorService(DirectorRepository directorRepository) { this.directorRepository = directorRepository; } public Director create(Director director) { - return (Director) directorRepository.save(director); + return directorRepository.save(director); } public void addFilm(Long directorId, Film film) { - Director director = (Director) directorRepository.findById(directorId) + Director director = directorRepository.findById(directorId) .orElseThrow(); director.addFilm(film); + directorRepository.save(director); } @@ -32,7 +33,7 @@ public DirectorDTO find(Long id) { public void delete(Long id) { - Director director = (Director) directorRepository.findById(id) + Director director = directorRepository.findById(id) .orElseThrow(); directorRepository.delete(director); diff --git a/src/main/java/org/example/Film.java b/src/main/java/org/example/Film.java new file mode 100644 index 00000000..eeb3ecba --- /dev/null +++ b/src/main/java/org/example/Film.java @@ -0,0 +1,67 @@ +package org.example; + +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import org.example.Director; + +import java.util.Objects; + +@Entity +public class Film extends BaseEntity{ + + + private Long id; + + @NotNull(message = "Title cannot be null") + @Size(min = 1, max = 255, message = "Title must be between 1 and 255 characters") + private String title; + @ManyToOne + + @NotNull(message = "A film must have a director") + 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); + } + + @Override + public int hashCode() { + return 31; + } +} diff --git a/src/main/java/org/example/Main.java b/src/main/java/org/example/Main.java new file mode 100644 index 00000000..e33e6a1e --- /dev/null +++ b/src/main/java/org/example/Main.java @@ -0,0 +1,50 @@ +package org.example; + +import jakarta.persistence.*; +import org.hibernate.jpa.HibernatePersistenceConfiguration; + +public class Main { + public static void main(String[] args) { + + + 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()) { + + // 2. The Service logic happens inside a transaction + emf.runInTransaction(em -> { + + DirectorRepositoryImpl directorRepository = new DirectorRepositoryImpl(emf); + Director d = new Director(); + try { + em.getTransaction().begin(); + em.getTransaction().commit(); + + em.close(); + emf.close(); + + + + + + + } catch (RuntimeException e) { + System.err.println("Error: " + e.getMessage()); + } + }); + + } + } + + + + +} diff --git a/src/main/java/org/example/Series.java b/src/main/java/org/example/Series.java new file mode 100644 index 00000000..4e936d17 --- /dev/null +++ b/src/main/java/org/example/Series.java @@ -0,0 +1,105 @@ +package org.example; + +import jakarta.persistence.*; +import org.example.Director; + +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +@Entity +public class Series extends BaseEntity{ + + + private Long id; + + @ManyToMany(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 setId(Long id) { + + this.id = id; + } + + 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; + } + + + + private static void add(Series s) { + } + + public Long getId() { + return id; + } + + 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 id != null && id.equals(other.id); +// } +// +// @Override +// public int hashCode() { +// return 31; +// } +} diff --git a/src/main/resources/META-INF/persistence.xml b/src/main/resources/META-INF/persistence.xml new file mode 100644 index 00000000..beaab145 --- /dev/null +++ b/src/main/resources/META-INF/persistence.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + From d253f7005a542befc5c0156aac36752e939ffaf5 Mon Sep 17 00:00:00 2001 From: JohanHiths Date: Fri, 9 Jan 2026 10:15:05 +0100 Subject: [PATCH 15/41] Add files via upload --- src/main/java/org/example/Director.java | 43 +++++-------------- .../java/org/example/DirectorService.java | 2 - src/main/java/org/example/Main.java | 2 +- 3 files changed, 12 insertions(+), 35 deletions(-) diff --git a/src/main/java/org/example/Director.java b/src/main/java/org/example/Director.java index da0ac69a..a03702c5 100644 --- a/src/main/java/org/example/Director.java +++ b/src/main/java/org/example/Director.java @@ -2,10 +2,6 @@ import jakarta.persistence.*; -import jakarta.validation.constraints.Max; -import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Size; import java.util.HashSet; import java.util.Set; @@ -13,7 +9,7 @@ public class Director extends BaseEntity{ - private Long id; + //private Long id; @OneToMany( mappedBy = "director", @@ -23,21 +19,20 @@ public class Director extends BaseEntity{ ) private Set films = new HashSet<>(); - @ManyToMany() + @ManyToMany + @JoinTable( + name = "director_series", + joinColumns = @JoinColumn(name = "director_id"), + inverseJoinColumns = @JoinColumn(name = "series_id")) private Set series = new HashSet<>(); - @NotBlank - @Size(max = 100) private String name; - @NotBlank private String country; - @Min(1850) - private int birthYear; + private Integer birthYear; + - @Column(nullable = true) - @Max(2100) private Integer yearOfDeath; @@ -58,11 +53,11 @@ public void setYearOfDeath(Integer yearOfDeath) { this.yearOfDeath = yearOfDeath; } - public int getBirthYear() { + public Integer getBirthYear() { return birthYear; } - public void setBirthYear(int birthYear) { + public void setBirthYear(Integer birthYear) { this.birthYear = birthYear; } @@ -82,10 +77,7 @@ public void setName(String name) { this.name = name; } - public void setId(Long id) { - this.id = id; - } public void addFilm(Film film) { films.add(film); @@ -109,19 +101,6 @@ public void removeSeries(Series s) { series.remove(s); } - public Long getId() { - return id; - } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Director)) return false; - Director other = (Director) o; - return id != null && id.equals(other.id); - } - @Override - public int hashCode() { - return 31; - } + } diff --git a/src/main/java/org/example/DirectorService.java b/src/main/java/org/example/DirectorService.java index 77343fe1..0639008c 100644 --- a/src/main/java/org/example/DirectorService.java +++ b/src/main/java/org/example/DirectorService.java @@ -24,14 +24,12 @@ public void addFilm(Long directorId, Film film) { directorRepository.save(director); } - public DirectorDTO find(Long id) { return directorRepository.findById(id) .map(d -> new DirectorDTO(d.getName(), d.getCountry())) .orElseThrow(() -> new RuntimeException("Director not found")); } - public void delete(Long id) { Director director = directorRepository.findById(id) .orElseThrow(); diff --git a/src/main/java/org/example/Main.java b/src/main/java/org/example/Main.java index e33e6a1e..6209657b 100644 --- a/src/main/java/org/example/Main.java +++ b/src/main/java/org/example/Main.java @@ -4,7 +4,7 @@ import org.hibernate.jpa.HibernatePersistenceConfiguration; public class Main { - public static void main(String[] args) { + static void main() { final PersistenceConfiguration cfg = new HibernatePersistenceConfiguration("emf") From 438577a77433e9c06a6c346ccf9871c219bbf23a Mon Sep 17 00:00:00 2001 From: JohanHiths Date: Sat, 10 Jan 2026 09:10:00 +0100 Subject: [PATCH 16/41] Add files via upload --- .../java/org/example/BaseRepositoryImpl.java | 4 ++-- src/main/java/org/example/Director.java | 2 +- .../java/org/example/DirectorService.java | 4 ++-- src/main/java/org/example/Main.java | 23 ++++++++++--------- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/example/BaseRepositoryImpl.java b/src/main/java/org/example/BaseRepositoryImpl.java index f25591ac..1f213427 100644 --- a/src/main/java/org/example/BaseRepositoryImpl.java +++ b/src/main/java/org/example/BaseRepositoryImpl.java @@ -64,7 +64,7 @@ public Iterable findAll() { @Override public boolean existsById(Long id) { Long count = em.createQuery( - "select count(e) from " + entityClass.getName() + " e where e.id = :id", + "select count(e) from " + entityClass.getSimpleName() + " e where e.id = :id", Long.class ).setParameter("id", id).getSingleResult(); return count > 0; @@ -74,7 +74,7 @@ public boolean existsById(Long id) { @Override public long count() { - return em.createQuery("select count(e) from " + entityClass.getName() + " e", Long.class).getSingleResult(); + return em.createQuery("select count(e) from " + entityClass.getSimpleName() + " e", Long.class).getSingleResult(); } @Override diff --git a/src/main/java/org/example/Director.java b/src/main/java/org/example/Director.java index a03702c5..513191d7 100644 --- a/src/main/java/org/example/Director.java +++ b/src/main/java/org/example/Director.java @@ -13,7 +13,7 @@ public class Director extends BaseEntity{ @OneToMany( mappedBy = "director", - cascade = CascadeType.PERSIST, + cascade = { CascadeType.PERSIST, CascadeType.MERGE }, orphanRemoval = true ) diff --git a/src/main/java/org/example/DirectorService.java b/src/main/java/org/example/DirectorService.java index 0639008c..22888f34 100644 --- a/src/main/java/org/example/DirectorService.java +++ b/src/main/java/org/example/DirectorService.java @@ -6,7 +6,7 @@ public class DirectorService { private final DirectorRepository directorRepository; - public DirectorService(DirectorRepository directorRepository) { + public DirectorService(DirectorRepository directorRepository) { this.directorRepository = directorRepository; } @@ -27,7 +27,7 @@ public void addFilm(Long directorId, Film film) { public DirectorDTO find(Long id) { return directorRepository.findById(id) .map(d -> new DirectorDTO(d.getName(), d.getCountry())) - .orElseThrow(() -> new RuntimeException("Director not found")); + .orElseThrow(() -> new RuntimeException("D irector not found")); } public void delete(Long id) { diff --git a/src/main/java/org/example/Main.java b/src/main/java/org/example/Main.java index 6209657b..9185cc0b 100644 --- a/src/main/java/org/example/Main.java +++ b/src/main/java/org/example/Main.java @@ -19,26 +19,27 @@ static void main() { try (EntityManagerFactory emf = cfg.createEntityManagerFactory()) { - // 2. The Service logic happens inside a transaction emf.runInTransaction(em -> { - DirectorRepositoryImpl directorRepository = new DirectorRepositoryImpl(emf); - Director d = new Director(); - try { - em.getTransaction().begin(); - em.getTransaction().commit(); - - em.close(); - emf.close(); - + try { + em.getTransaction().begin(); + DirectorRepositoryImpl directorRepository = new DirectorRepositoryImpl(emf); + Director d = new Director(); + d.setName("John Doe"); + directorRepository.save(d); - } catch (RuntimeException e) { + em.getTransaction().commit(); + + } catch (Exception e) { System.err.println("Error: " + e.getMessage()); + } finally { + em.close(); } + }); } From b27871cccea04f7966273f1f86cf1d24953f65ac Mon Sep 17 00:00:00 2001 From: JohanHiths Date: Sat, 10 Jan 2026 09:15:08 +0100 Subject: [PATCH 17/41] Add files via upload --- src/main/java/org/example/Film.java | 14 ++------------ src/main/java/org/example/Series.java | 16 ++++------------ 2 files changed, 6 insertions(+), 24 deletions(-) diff --git a/src/main/java/org/example/Film.java b/src/main/java/org/example/Film.java index eeb3ecba..cf97066d 100644 --- a/src/main/java/org/example/Film.java +++ b/src/main/java/org/example/Film.java @@ -1,7 +1,7 @@ package org.example; import jakarta.persistence.*; -import jakarta.validation.constraints.*; + import org.example.Director; import java.util.Objects; @@ -9,15 +9,12 @@ @Entity public class Film extends BaseEntity{ - private Long id; - @NotNull(message = "Title cannot be null") - @Size(min = 1, max = 255, message = "Title must be between 1 and 255 characters") private String title; @ManyToOne - @NotNull(message = "A film must have a director") + private Director director; public Director getDirector() { @@ -45,13 +42,6 @@ public Long getId() { return id; } - - - - - - - @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/main/java/org/example/Series.java b/src/main/java/org/example/Series.java index 4e936d17..4d04926c 100644 --- a/src/main/java/org/example/Series.java +++ b/src/main/java/org/example/Series.java @@ -1,19 +1,17 @@ package org.example; import jakarta.persistence.*; -import org.example.Director; import java.util.HashSet; -import java.util.Objects; import java.util.Set; @Entity public class Series extends BaseEntity{ - private Long id; - @ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }) + @ManyToMany + (mappedBy = "series", cascade = { CascadeType.PERSIST, CascadeType.MERGE}) private Set directors = new HashSet<>(); private String title; @@ -22,10 +20,7 @@ public class Series extends BaseEntity{ private Integer lastAired; private String starActors; - public void setId(Long id) { - this.id = id; - } public void setTitle(String title) { @@ -59,12 +54,9 @@ public void setStarActors(String starActors) { - private static void add(Series s) { - } - public Long getId() { - return id; - } + + public String getTitle() { return title; From 41fcca005670e61e7187b85a396a2c17a48dbc09 Mon Sep 17 00:00:00 2001 From: Mattias Barth Date: Mon, 12 Jan 2026 11:03:18 +0100 Subject: [PATCH 18/41] fixed issues that CodeRabbit highlighted --- src/main/java/org/example/BaseRepositoryImpl.java | 5 ++--- src/main/java/org/example/Director.java | 2 +- src/main/java/org/example/DirectorService.java | 8 ++++---- src/main/java/org/example/Series.java | 2 ++ src/main/resources/META-INF/persistence.xml | 2 +- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/example/BaseRepositoryImpl.java b/src/main/java/org/example/BaseRepositoryImpl.java index 1f213427..542fbb85 100644 --- a/src/main/java/org/example/BaseRepositoryImpl.java +++ b/src/main/java/org/example/BaseRepositoryImpl.java @@ -16,16 +16,15 @@ public BaseRepositoryImpl(EntityManager em, Class entityClass) { } + @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 { + } else { return em.merge(entity); } } diff --git a/src/main/java/org/example/Director.java b/src/main/java/org/example/Director.java index 513191d7..cd6e5f12 100644 --- a/src/main/java/org/example/Director.java +++ b/src/main/java/org/example/Director.java @@ -22,7 +22,7 @@ public class Director extends BaseEntity{ @ManyToMany @JoinTable( name = "director_series", - joinColumns = @JoinColumn(name = "director_id"), + joinColumns = @JoinColumn(name = "directors_id"), inverseJoinColumns = @JoinColumn(name = "series_id")) private Set series = new HashSet<>(); diff --git a/src/main/java/org/example/DirectorService.java b/src/main/java/org/example/DirectorService.java index 22888f34..ef543abd 100644 --- a/src/main/java/org/example/DirectorService.java +++ b/src/main/java/org/example/DirectorService.java @@ -17,11 +17,11 @@ public Director create(Director director) { public void addFilm(Long directorId, Film film) { - Director director = directorRepository.findById(directorId) - .orElseThrow(); + Director director = directorRepository.findById(directorId) + .orElseThrow(() -> new RuntimeException("Director not found: " + directorId)); director.addFilm(film); - directorRepository.save(director); + directorRepository.save(director); } public DirectorDTO find(Long id) { @@ -32,7 +32,7 @@ public DirectorDTO find(Long id) { public void delete(Long id) { Director director = directorRepository.findById(id) - .orElseThrow(); + .orElseThrow(() -> new RuntimeException("Director not found: " + id)); directorRepository.delete(director); } diff --git a/src/main/java/org/example/Series.java b/src/main/java/org/example/Series.java index 4d04926c..e2e3665a 100644 --- a/src/main/java/org/example/Series.java +++ b/src/main/java/org/example/Series.java @@ -8,6 +8,8 @@ @Entity public class Series extends BaseEntity{ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToMany diff --git a/src/main/resources/META-INF/persistence.xml b/src/main/resources/META-INF/persistence.xml index beaab145..fdd34a29 100644 --- a/src/main/resources/META-INF/persistence.xml +++ b/src/main/resources/META-INF/persistence.xml @@ -12,7 +12,7 @@ - + From 02a6b0e92a472586b62b81e4a73f7a5efac92a85 Mon Sep 17 00:00:00 2001 From: Mattias Barth Date: Mon, 12 Jan 2026 11:57:31 +0100 Subject: [PATCH 19/41] Fix some more issues from CodeRabbit, clean up some code. --- src/main/java/org/example/Director.java | 1 + .../java/org/example/DirectorService.java | 13 ++++-- src/main/java/org/example/Film.java | 7 +++ src/main/java/org/example/Main.java | 46 +++++++++---------- src/main/java/org/example/Series.java | 11 +---- 5 files changed, 40 insertions(+), 38 deletions(-) diff --git a/src/main/java/org/example/Director.java b/src/main/java/org/example/Director.java index cd6e5f12..00e4b53a 100644 --- a/src/main/java/org/example/Director.java +++ b/src/main/java/org/example/Director.java @@ -24,6 +24,7 @@ public class Director extends BaseEntity{ name = "director_series", joinColumns = @JoinColumn(name = "directors_id"), inverseJoinColumns = @JoinColumn(name = "series_id")) + private Set series = new HashSet<>(); private String name; diff --git a/src/main/java/org/example/DirectorService.java b/src/main/java/org/example/DirectorService.java index ef543abd..b4dd7ef2 100644 --- a/src/main/java/org/example/DirectorService.java +++ b/src/main/java/org/example/DirectorService.java @@ -38,10 +38,13 @@ public void delete(Long id) { } public Director findDirector(Long id) { - Director director = (Director) directorRepository.findById(id) - .orElseThrow(); - - return director; - + //Old code +// Director director = (Director) directorRepository.findById(id) +// .orElseThrow(); +// +// return director; + //New code + return directorRepository.findById(id) + .orElseThrow(() -> new RuntimeException("Director not found: " + id)); } } diff --git a/src/main/java/org/example/Film.java b/src/main/java/org/example/Film.java index cf97066d..41add0ee 100644 --- a/src/main/java/org/example/Film.java +++ b/src/main/java/org/example/Film.java @@ -9,6 +9,13 @@ @Entity public class Film extends BaseEntity{ + /* + Remove duplicate id field that shadows BaseEntity's @Id mapping + + Film extends BaseEntity, which already defines @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id. + The duplicate private Long id declaration on line 12 shadows the inherited id and breaks JPA entity mapping. + The corresponding setId/getId methods (lines 36–42) operate on this shadow field instead of the actual mapped id from BaseEntity. + */ private Long id; private String title; diff --git a/src/main/java/org/example/Main.java b/src/main/java/org/example/Main.java index 9185cc0b..44908c3a 100644 --- a/src/main/java/org/example/Main.java +++ b/src/main/java/org/example/Main.java @@ -21,31 +21,29 @@ static void main() { emf.runInTransaction(em -> { - - - - try { - em.getTransaction().begin(); - DirectorRepositoryImpl directorRepository = new DirectorRepositoryImpl(emf); - Director d = new Director(); - d.setName("John Doe"); - - directorRepository.save(d); - - em.getTransaction().commit(); - - } catch (Exception e) { - System.err.println("Error: " + e.getMessage()); - } finally { - em.close(); - } - + //Old code that CodeRabbit suggested to remove +// try { +// em.getTransaction().begin(); +// DirectorRepositoryImpl directorRepository = new DirectorRepositoryImpl(emf); +// Director d = new Director(); +// d.setName("John Doe"); +// +// directorRepository.save(d); +// +// em.getTransaction().commit(); +// +// } catch (Exception e) { +// System.err.println("Error: " + e.getMessage()); +// +// } finally { +// em.close(); +// } + Director d = new Director(); + d.setName("Example Director"); + d.setCountry("USA"); + d.setBirthYear(1970); + em.persist(d); }); - } } - - - - } diff --git a/src/main/java/org/example/Series.java b/src/main/java/org/example/Series.java index e2e3665a..2a6c2d61 100644 --- a/src/main/java/org/example/Series.java +++ b/src/main/java/org/example/Series.java @@ -10,10 +10,9 @@ public class Series extends BaseEntity{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; + private Long id; //CodeRabbit suggests removing this line, but it gives errors below - @ManyToMany - (mappedBy = "series", cascade = { CascadeType.PERSIST, CascadeType.MERGE}) + @ManyToMany(mappedBy = "series", cascade = { CascadeType.PERSIST, CascadeType.MERGE}) private Set directors = new HashSet<>(); private String title; @@ -54,12 +53,6 @@ public void setStarActors(String starActors) { this.starActors = starActors; } - - - - - - public String getTitle() { return title; } From 0066a05dca0bd227aa56fcfc7772e6972d929134 Mon Sep 17 00:00:00 2001 From: Mattias Barth Date: Mon, 12 Jan 2026 11:59:44 +0100 Subject: [PATCH 20/41] Remove Director, Film and Main from Java-root. --- src/main/java/Director.java | 76 ------------------------------------- src/main/java/Film.java | 39 ------------------- src/main/java/Main.java | 42 -------------------- 3 files changed, 157 deletions(-) delete mode 100644 src/main/java/Director.java delete mode 100644 src/main/java/Film.java delete mode 100644 src/main/java/Main.java diff --git a/src/main/java/Director.java b/src/main/java/Director.java deleted file mode 100644 index f34554c3..00000000 --- a/src/main/java/Director.java +++ /dev/null @@ -1,76 +0,0 @@ -import jakarta.persistence.*; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -@Entity -public class Director { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @OneToMany(mappedBy = "director") - private Set films = new HashSet<>(); - - private String name; - private String country; - private int birthYear; - @Column(nullable = true) - private Integer yearOfDeath; - - - - 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 int getBirthYear() { - return birthYear; - } - - public void setBirthYear(int 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 setId(Long id) { - this.id = id; - } - - public Long getId() { - return id; - } - - -} - - diff --git a/src/main/java/Film.java b/src/main/java/Film.java deleted file mode 100644 index 6beaac82..00000000 --- a/src/main/java/Film.java +++ /dev/null @@ -1,39 +0,0 @@ -import jakarta.persistence.*; - -@Entity -public class Film { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - private String title; - @ManyToOne - @JoinColumn(name = "director_id") - 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; - } - - -} diff --git a/src/main/java/Main.java b/src/main/java/Main.java deleted file mode 100644 index d6254896..00000000 --- a/src/main/java/Main.java +++ /dev/null @@ -1,42 +0,0 @@ -import jakarta.persistence.Entity; -import jakarta.persistence.EntityManagerFactory; -import jakarta.persistence.Persistence; -import jakarta.persistence.PersistenceConfiguration; -import org.hibernate.jpa.HibernatePersistenceConfiguration; - -import java.util.List; - -public class Main { - public static void main(String[] args) { - - - final PersistenceConfiguration cfg = new HibernatePersistenceConfiguration("emf") - .jdbcUrl("jdbc:mysql://localhost:3306/film_database") - .jdbcUsername("root") - .jdbcPassword("root") - .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); - try (EntityManagerFactory emf = cfg.createEntityManagerFactory()) { - emf.runInTransaction(em -> { - //If no Films in database, add some - if (em.createQuery("select count(o) from Film o", Long.class) - .getSingleResult() == 0) { - Film film1 = new Film(); - em.persist(film1); - em.flush(); - Film film2 = new Film(); - em.persist(film2); - } - System.out.println("==== Using select query, N + 1 ===="); - em.createQuery("from Film", Film.class) - .getResultList().forEach(System.out::println); - - }); - - } - - } -} From 9bf2acab5d359ccae40283f56f597f40c28f97b1 Mon Sep 17 00:00:00 2001 From: Mattias Barth Date: Mon, 12 Jan 2026 13:35:19 +0100 Subject: [PATCH 21/41] update Directory.java and DirectorRepositoryImpl.java Co-authored-by: JohanHiths --- src/main/java/org/example/DirectorRepositoryImpl.java | 10 ++++++++-- src/main/java/org/example/Film.java | 1 - 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/example/DirectorRepositoryImpl.java b/src/main/java/org/example/DirectorRepositoryImpl.java index 659d096c..ae16769f 100644 --- a/src/main/java/org/example/DirectorRepositoryImpl.java +++ b/src/main/java/org/example/DirectorRepositoryImpl.java @@ -14,12 +14,18 @@ public DirectorRepositoryImpl(EntityManagerFactory em) { @Override public Optional findByName(String name) { - + try { return em.createQuery("SELECT d FROM Director d WHERE d.name = :name", Director.class) .setParameter("name", name) .getResultStream() .findFirst(); - } + } catch (Exception e) { + System.err.println("Error: " + e.getMessage()); + } finally { + em.close(); + } + return Optional.empty(); + } } diff --git a/src/main/java/org/example/Film.java b/src/main/java/org/example/Film.java index 41add0ee..77675fc4 100644 --- a/src/main/java/org/example/Film.java +++ b/src/main/java/org/example/Film.java @@ -45,7 +45,6 @@ public void setId(Long id) { } public Long getId() { - return id; } From 55889b03e062a2ee2b68de49ce520115e9af94cd Mon Sep 17 00:00:00 2001 From: Mattias Barth Date: Mon, 12 Jan 2026 13:48:04 +0100 Subject: [PATCH 22/41] Fixed problems identified by CodeRabbit Co-authored-by: JohanHiths --- src/main/java/org/example/Director.java | 3 ++- .../java/org/example/DirectorRepository.java | 2 +- .../java/org/example/DirectorService.java | 2 +- src/main/java/org/example/Film.java | 26 +++++++------------ src/main/java/org/example/Main.java | 2 +- src/main/java/org/example/Series.java | 6 ++--- 6 files changed, 18 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/example/Director.java b/src/main/java/org/example/Director.java index 00e4b53a..be6420ea 100644 --- a/src/main/java/org/example/Director.java +++ b/src/main/java/org/example/Director.java @@ -1,6 +1,7 @@ package org.example; import jakarta.persistence.*; +import org.hibernate.engine.internal.Cascade; import java.util.HashSet; import java.util.Set; @@ -19,7 +20,7 @@ public class Director extends BaseEntity{ ) private Set films = new HashSet<>(); - @ManyToMany + @ManyToMany( cascade = { CascadeType.PERSIST, CascadeType.MERGE }) @JoinTable( name = "director_series", joinColumns = @JoinColumn(name = "directors_id"), diff --git a/src/main/java/org/example/DirectorRepository.java b/src/main/java/org/example/DirectorRepository.java index 04531991..e91372a5 100644 --- a/src/main/java/org/example/DirectorRepository.java +++ b/src/main/java/org/example/DirectorRepository.java @@ -2,6 +2,6 @@ import java.util.Optional; -public interface DirectorRepository extends Repository { +public interface DirectorRepository extends Repository { Optional findByName(String name); } diff --git a/src/main/java/org/example/DirectorService.java b/src/main/java/org/example/DirectorService.java index b4dd7ef2..e795f490 100644 --- a/src/main/java/org/example/DirectorService.java +++ b/src/main/java/org/example/DirectorService.java @@ -27,7 +27,7 @@ public void addFilm(Long directorId, Film film) { public DirectorDTO find(Long id) { return directorRepository.findById(id) .map(d -> new DirectorDTO(d.getName(), d.getCountry())) - .orElseThrow(() -> new RuntimeException("D irector not found")); + .orElseThrow(() -> new RuntimeException("Director not found")); } public void delete(Long id) { diff --git a/src/main/java/org/example/Film.java b/src/main/java/org/example/Film.java index 77675fc4..9464a477 100644 --- a/src/main/java/org/example/Film.java +++ b/src/main/java/org/example/Film.java @@ -9,14 +9,7 @@ @Entity public class Film extends BaseEntity{ - /* - Remove duplicate id field that shadows BaseEntity's @Id mapping - - Film extends BaseEntity, which already defines @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id. - The duplicate private Long id declaration on line 12 shadows the inherited id and breaks JPA entity mapping. - The corresponding setId/getId methods (lines 36–42) operate on this shadow field instead of the actual mapped id from BaseEntity. - */ - private Long id; + //private Long id; private String title; @ManyToOne @@ -40,20 +33,21 @@ public void setTitle(String title) { this.title = title; } - public void setId(Long id) { - this.id = id; - } - - public Long getId() { - return id; - } +// 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 id != null && id.equals(other.id); + return getId() != null && getId().equals(other.getId()); } @Override diff --git a/src/main/java/org/example/Main.java b/src/main/java/org/example/Main.java index 44908c3a..5d1c4740 100644 --- a/src/main/java/org/example/Main.java +++ b/src/main/java/org/example/Main.java @@ -4,7 +4,7 @@ import org.hibernate.jpa.HibernatePersistenceConfiguration; public class Main { - static void main() { + public static void main(String[] args) { final PersistenceConfiguration cfg = new HibernatePersistenceConfiguration("emf") diff --git a/src/main/java/org/example/Series.java b/src/main/java/org/example/Series.java index 2a6c2d61..c198cfd4 100644 --- a/src/main/java/org/example/Series.java +++ b/src/main/java/org/example/Series.java @@ -8,9 +8,9 @@ @Entity public class Series extends BaseEntity{ - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; //CodeRabbit suggests removing this line, but it gives errors below +// @Id +// @GeneratedValue(strategy = GenerationType.IDENTITY) + //private Long id; //CodeRabbit suggests removing this line, but it gives errors below @ManyToMany(mappedBy = "series", cascade = { CascadeType.PERSIST, CascadeType.MERGE}) private Set directors = new HashSet<>(); From 887f1e15f452c3fc5474545830eff01779b68e0f Mon Sep 17 00:00:00 2001 From: Mattias Barth Date: Mon, 12 Jan 2026 14:10:37 +0100 Subject: [PATCH 23/41] Fixed problems identified by CodeRabbit Co-authored-by: JohanHiths --- .../org/example/DirectorRepositoryImpl.java | 8 ------ src/main/java/org/example/Series.java | 28 ++++++++----------- 2 files changed, 12 insertions(+), 24 deletions(-) diff --git a/src/main/java/org/example/DirectorRepositoryImpl.java b/src/main/java/org/example/DirectorRepositoryImpl.java index ae16769f..f83ac18a 100644 --- a/src/main/java/org/example/DirectorRepositoryImpl.java +++ b/src/main/java/org/example/DirectorRepositoryImpl.java @@ -14,18 +14,10 @@ public DirectorRepositoryImpl(EntityManagerFactory em) { @Override public Optional findByName(String name) { - try { return em.createQuery("SELECT d FROM Director d WHERE d.name = :name", Director.class) .setParameter("name", name) .getResultStream() .findFirst(); - } catch (Exception e) { - System.err.println("Error: " + e.getMessage()); - } finally { - em.close(); - } - - return Optional.empty(); } } diff --git a/src/main/java/org/example/Series.java b/src/main/java/org/example/Series.java index c198cfd4..93f248e6 100644 --- a/src/main/java/org/example/Series.java +++ b/src/main/java/org/example/Series.java @@ -8,10 +8,6 @@ @Entity public class Series extends BaseEntity{ -// @Id -// @GeneratedValue(strategy = GenerationType.IDENTITY) - //private Long id; //CodeRabbit suggests removing this line, but it gives errors below - @ManyToMany(mappedBy = "series", cascade = { CascadeType.PERSIST, CascadeType.MERGE}) private Set directors = new HashSet<>(); @@ -77,16 +73,16 @@ 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 id != null && id.equals(other.id); -// } -// -// @Override -// public int hashCode() { -// return 31; -// } + @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; + } } From ad87eed882a6761c044d3c5d06323fac40d61a9f Mon Sep 17 00:00:00 2001 From: Mattias Barth Date: Mon, 12 Jan 2026 14:17:17 +0100 Subject: [PATCH 24/41] Add FilmDTO, FilmRepository, FilmRepository, FilmService abd update FilmDTO Co-authored-by: JohanHiths --- src/main/java/org/example/FilmDTO.java | 7 +++++++ src/main/java/org/example/FilmRepository.java | 4 ++++ src/main/java/org/example/FilmRepositoryImpl.java | 4 ++++ src/main/java/org/example/FilmService.java | 4 ++++ 4 files changed, 19 insertions(+) create mode 100644 src/main/java/org/example/FilmDTO.java create mode 100644 src/main/java/org/example/FilmRepository.java create mode 100644 src/main/java/org/example/FilmRepositoryImpl.java create mode 100644 src/main/java/org/example/FilmService.java 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..998810f5 --- /dev/null +++ b/src/main/java/org/example/FilmRepository.java @@ -0,0 +1,4 @@ +package org.example; + +public class FilmRepository { +} diff --git a/src/main/java/org/example/FilmRepositoryImpl.java b/src/main/java/org/example/FilmRepositoryImpl.java new file mode 100644 index 00000000..d96aae60 --- /dev/null +++ b/src/main/java/org/example/FilmRepositoryImpl.java @@ -0,0 +1,4 @@ +package org.example; + +public class FilmRepositoryImpl { +} diff --git a/src/main/java/org/example/FilmService.java b/src/main/java/org/example/FilmService.java new file mode 100644 index 00000000..f302fc53 --- /dev/null +++ b/src/main/java/org/example/FilmService.java @@ -0,0 +1,4 @@ +package org.example; + +public class FilmService { +} From daa00c83ba21d1bcfbcfaa5836c856fc757d7820 Mon Sep 17 00:00:00 2001 From: Mattias Barth Date: Mon, 12 Jan 2026 14:33:19 +0100 Subject: [PATCH 25/41] Update FilmRepository, FilmRepositoryImpl and FilmService Co-authored-by: JohanHiths --- src/main/java/org/example/FilmRepository.java | 5 +++- .../java/org/example/FilmRepositoryImpl.java | 19 +++++++++++++- src/main/java/org/example/FilmService.java | 25 +++++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/example/FilmRepository.java b/src/main/java/org/example/FilmRepository.java index 998810f5..d841949b 100644 --- a/src/main/java/org/example/FilmRepository.java +++ b/src/main/java/org/example/FilmRepository.java @@ -1,4 +1,7 @@ package org.example; -public class FilmRepository { +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 index d96aae60..bee9856b 100644 --- a/src/main/java/org/example/FilmRepositoryImpl.java +++ b/src/main/java/org/example/FilmRepositoryImpl.java @@ -1,4 +1,21 @@ package org.example; -public class FilmRepositoryImpl { +import jakarta.persistence.EntityManager; + +import java.util.Optional; + +public class FilmRepositoryImpl extends BaseRepositoryImpl implements FilmRepository { + + public FilmRepositoryImpl(EntityManager em) { + super(em.createEntityManager(), Film.class); + } + + @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 index f302fc53..e5868c16 100644 --- a/src/main/java/org/example/FilmService.java +++ b/src/main/java/org/example/FilmService.java @@ -1,4 +1,29 @@ 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 FilmDTO find(Long id) { + return filmRepository.findById(id) + .map(f -> new FilmDTO(f.getTitle())) + .orElseThrow(() -> new RuntimeException("Film not found: " + id)); + } + + public Film findFilm(Long id) { + return filmRepository.findById(id) + .orElseThrow(() -> new RuntimeException("Film not found: " + id)); + } } From effd2b1856d8ad5051aaae7b0860e51a1b561880 Mon Sep 17 00:00:00 2001 From: Mattias Barth Date: Mon, 12 Jan 2026 14:36:02 +0100 Subject: [PATCH 26/41] update FilmRepositoryImpl Co-authored-by: JohanHiths --- src/main/java/org/example/DirectorRepositoryImpl.java | 1 - src/main/java/org/example/FilmRepositoryImpl.java | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/example/DirectorRepositoryImpl.java b/src/main/java/org/example/DirectorRepositoryImpl.java index f83ac18a..068389fc 100644 --- a/src/main/java/org/example/DirectorRepositoryImpl.java +++ b/src/main/java/org/example/DirectorRepositoryImpl.java @@ -1,6 +1,5 @@ package org.example; -import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; import java.util.Optional; diff --git a/src/main/java/org/example/FilmRepositoryImpl.java b/src/main/java/org/example/FilmRepositoryImpl.java index bee9856b..f18ffe3e 100644 --- a/src/main/java/org/example/FilmRepositoryImpl.java +++ b/src/main/java/org/example/FilmRepositoryImpl.java @@ -1,12 +1,12 @@ package org.example; -import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; import java.util.Optional; public class FilmRepositoryImpl extends BaseRepositoryImpl implements FilmRepository { - public FilmRepositoryImpl(EntityManager em) { + public FilmRepositoryImpl(EntityManagerFactory em) { super(em.createEntityManager(), Film.class); } From d330599ba6b3d8f21c16de77b58d9cb3cd7c0e86 Mon Sep 17 00:00:00 2001 From: Edvin Sandgren <229709012+EdvinSandgren@users.noreply.github.com> Date: Tue, 13 Jan 2026 08:00:26 +0100 Subject: [PATCH 27/41] Updates Director Menu in CLI to implement methods in DirectorService --- src/main/java/{ => org/example}/CLI.java | 69 ++++++++++++++++++------ 1 file changed, 53 insertions(+), 16 deletions(-) rename src/main/java/{ => org/example}/CLI.java (73%) diff --git a/src/main/java/CLI.java b/src/main/java/org/example/CLI.java similarity index 73% rename from src/main/java/CLI.java rename to src/main/java/org/example/CLI.java index d227b66e..4e5c8bb6 100644 --- a/src/main/java/CLI.java +++ b/src/main/java/org/example/CLI.java @@ -1,9 +1,9 @@ -import jakarta.persistence.EntityManager; +package org.example; -import java.io.IOException; +import jakarta.persistence.EntityManager; public class CLI { - private final String os = System.getProperty("os.name"); + //private final String os = System.getProperty("os.name"); EntityManager em; void mainMenu(EntityManager entityManager) { //throws IOException, InterruptedException { @@ -64,36 +64,73 @@ private void directorMenu() { //throws IOException, InterruptedException { private void createDirector() { //throws IOException, InterruptedException { //clearConsole(); - String name = IO.readln("Enter the full name of the Director: "); - String country = IO.readln("Enter the country of the Director: "); - int birthYear = Integer.parseInt(IO.readln("Enter the birth year of the Director: ")); - Integer yearOfDeath = Integer.valueOf(IO.readln("Enter the year of death of the Director." + - "If they're alive, leave blank: ")); + 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." + + "If they're alive, leave blank: ")); + } catch (NumberFormatException _) { + } - //TODO: - //send information to create-method in Director class + 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(Director.findAll(em)); + IO.println(DirectorService.findDirector()); } private void listSpecificDirector() { - String name = IO.readln("Enter the name of the Director: "); - IO.println(Director.findByName(em, name)); + Long id = Long.valueOf(IO.readln("Enter the ID of the Director: ")); + IO.println(DirectorService.findDirector(id).getName()); } 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." + "If 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 = Integer.valueOf(IO.readln("Enter the birth year of the Director: ")); - Integer yearOfDeath = Integer.valueOf(IO.readln("Enter the year of death 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 _) { + } //TODO: //Determine which values aren't null, and update them + Director updatedDirector = DirectorService.findDirector(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.create(updatedDirector); + } private void filmMenu() { //throws IOException, InterruptedException { @@ -126,7 +163,7 @@ private void createFilm() { //throws IOException, InterruptedException { String title = IO.readln("Enter the title of the Film: "); //TODO: - //send information to create-method in Film class + //send information to create-method in org.example.Film class } private void listFilms() { From 01bf50a97f0eec92f4c73c6edf28bac7e2254f2e Mon Sep 17 00:00:00 2001 From: Mattias Barth Date: Tue, 13 Jan 2026 12:36:56 +0100 Subject: [PATCH 28/41] add and add code to SeriesDTO, SeriesRepository, SeriesRepositoryImpl, SeriesService --- src/main/java/org/example/SeriesDTO.java | 11 ++++++ .../java/org/example/SeriesRepository.java | 7 ++++ .../org/example/SeriesRepositoryImpl.java | 21 +++++++++++ src/main/java/org/example/SeriesService.java | 36 +++++++++++++++++++ 4 files changed, 75 insertions(+) create mode 100644 src/main/java/org/example/SeriesDTO.java create mode 100644 src/main/java/org/example/SeriesRepository.java create mode 100644 src/main/java/org/example/SeriesRepositoryImpl.java create mode 100644 src/main/java/org/example/SeriesService.java 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..8a0e8ef2 --- /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 findByName(String name); +} diff --git a/src/main/java/org/example/SeriesRepositoryImpl.java b/src/main/java/org/example/SeriesRepositoryImpl.java new file mode 100644 index 00000000..bdd6512d --- /dev/null +++ b/src/main/java/org/example/SeriesRepositoryImpl.java @@ -0,0 +1,21 @@ +package org.example; + +import jakarta.persistence.EntityManagerFactory; + +import java.util.Optional; + +public class SeriesRepositoryImpl extends BaseRepositoryImpl implements SeriesRepository { + + public SeriesRepositoryImpl(EntityManagerFactory em) { + + super(em.createEntityManager(), Series.class); + } + + @Override + public Optional findByName(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..fdf65fc0 --- /dev/null +++ b/src/main/java/org/example/SeriesService.java @@ -0,0 +1,36 @@ +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 FilmDTO find(Long id) { + return seriesRepository.findById(id) + .map(s -> new SeriesDTO(s.getTitle())) + .orElseThrow(() -> new RuntimeException("Series not found: " + id)); + } + + public Series findSeries(Long id) { + return seriesRepository.findById(id) + .orElseThrow(() -> new RuntimeException("Series not found: " + id)); + } +} From 3c10c4239529fbc186426c5d6132604170b78e8e Mon Sep 17 00:00:00 2001 From: JohanHiths Date: Tue, 13 Jan 2026 14:26:33 +0100 Subject: [PATCH 29/41] Add files via upload --- .../java/org/example/DirectorService.java | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/example/DirectorService.java b/src/main/java/org/example/DirectorService.java index 22888f34..8a20ee87 100644 --- a/src/main/java/org/example/DirectorService.java +++ b/src/main/java/org/example/DirectorService.java @@ -17,19 +17,36 @@ public Director create(Director director) { public void addFilm(Long directorId, Film film) { - Director director = directorRepository.findById(directorId) + Director director = directorRepository.findById(directorId) .orElseThrow(); director.addFilm(film); - directorRepository.save(director); + directorRepository.save(director); } - public DirectorDTO find(Long id) { - return directorRepository.findById(id) - .map(d -> new DirectorDTO(d.getName(), d.getCountry())) - .orElseThrow(() -> new RuntimeException("D irector not found")); + public Director update(Long id, 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); + } + return directorRepository.save(existingDirector); + } + + + public Iterable findAll() { + return directorRepository.findAll(); + } + public void delete(Long id) { Director director = directorRepository.findById(id) .orElseThrow(); @@ -45,3 +62,8 @@ public Director findDirector(Long id) { } } + // public DirectorDTO find(Long id) { +// return directorRepository.findById(id) +// .map(d -> new DirectorDTO(d.getName(), d.getCountry())) +// .orElseThrow(() -> new RuntimeException("Director not found")); +// } From 9b8ceaac8780daf928912e29f0fbb32a51a48785 Mon Sep 17 00:00:00 2001 From: Mattias Barth Date: Tue, 13 Jan 2026 21:26:40 +0100 Subject: [PATCH 30/41] update BaseRepositoryImpl, DirectorRepositoryImpl and SeriesService after CodeRabbit suggestions. --- src/main/java/org/example/BaseRepositoryImpl.java | 3 ++- src/main/java/org/example/DirectorRepositoryImpl.java | 7 ++++++- src/main/java/org/example/SeriesService.java | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/example/BaseRepositoryImpl.java b/src/main/java/org/example/BaseRepositoryImpl.java index 542fbb85..dfe622ac 100644 --- a/src/main/java/org/example/BaseRepositoryImpl.java +++ b/src/main/java/org/example/BaseRepositoryImpl.java @@ -10,7 +10,8 @@ public class BaseRepositoryImpl implements Rep protected Class entityClass; - public BaseRepositoryImpl(EntityManager em, Class entityClass) { +// public BaseRepositoryImpl(EntityManager em, Class entityClass) { +public BaseRepositoryImpl(Class entityClass) { this.em = em; this.entityClass = entityClass; } diff --git a/src/main/java/org/example/DirectorRepositoryImpl.java b/src/main/java/org/example/DirectorRepositoryImpl.java index 068389fc..c8f94eaf 100644 --- a/src/main/java/org/example/DirectorRepositoryImpl.java +++ b/src/main/java/org/example/DirectorRepositoryImpl.java @@ -4,11 +4,16 @@ 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(em.createEntityManager(), Director.class); + super(Director.class); + this.emf = em; } @Override diff --git a/src/main/java/org/example/SeriesService.java b/src/main/java/org/example/SeriesService.java index fdf65fc0..47be1ada 100644 --- a/src/main/java/org/example/SeriesService.java +++ b/src/main/java/org/example/SeriesService.java @@ -23,9 +23,9 @@ public void update(Series series) { seriesRepository.save(series); } - public FilmDTO find(Long id) { + public SeriesDTO find(Long id) { return seriesRepository.findById(id) - .map(s -> new SeriesDTO(s.getTitle())) + .map(SeriesDTO::new) .orElseThrow(() -> new RuntimeException("Series not found: " + id)); } From 109988c792a2899638def839fd849dc4d54c9ee8 Mon Sep 17 00:00:00 2001 From: Edvin Sandgren <229709012+EdvinSandgren@users.noreply.github.com> Date: Wed, 14 Jan 2026 09:14:10 +0100 Subject: [PATCH 31/41] Updates menus to implement methods in Service classes for CRUD operations --- src/main/java/org/example/CLI.java | 168 ++++++++++++++++++++++------- 1 file changed, 130 insertions(+), 38 deletions(-) diff --git a/src/main/java/org/example/CLI.java b/src/main/java/org/example/CLI.java index 4e5c8bb6..353819d4 100644 --- a/src/main/java/org/example/CLI.java +++ b/src/main/java/org/example/CLI.java @@ -4,12 +4,22 @@ public class CLI { //private final String os = System.getProperty("os.name"); - EntityManager em; + DirectorService directorService; + FilmService filmService; + SeriesService seriesService; - void mainMenu(EntityManager entityManager) { //throws IOException, InterruptedException { + void cliStart(DirectorService directorService, FilmService filmService, SeriesService seriesService){ + this.directorService = directorService; + this.filmService = filmService; + this.seriesService = seriesService; + + mainMenu(); + } + + void mainMenu() { //throws IOException, InterruptedException { while(true) { //clearConsole(); - em = entityManager; + System.out.println(""" Welcome to the Film Database! @@ -57,7 +67,7 @@ private void directorMenu() { //throws IOException, InterruptedException { case "2" -> listDirectors(); case "3" -> listSpecificDirector(); case "4" -> updateDirector(); - case "5" -> mainMenu(em); + case "5" -> mainMenu(); default -> invalidInput(); } } @@ -74,7 +84,7 @@ private void createDirector() { //throws IOException, InterruptedException { 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." + - "If they're alive, leave blank: ")); + "If they're alive, leave blank: ")); } catch (NumberFormatException _) { } @@ -83,7 +93,7 @@ private void createDirector() { //throws IOException, InterruptedException { newDirector.setCountry(country); newDirector.setBirthYear(birthYear); newDirector.setYearOfDeath(yearOfDeath); - DirectorService.create(newDirector); + directorService.create(newDirector); } catch (NumberFormatException e) { System.out.println("Invalid input!"); @@ -91,12 +101,27 @@ private void createDirector() { //throws IOException, InterruptedException { } private void listDirectors() { - IO.println(DirectorService.findDirector()); + IO.println(directorService.findAllDirectors()); } private void listSpecificDirector() { - Long id = Long.valueOf(IO.readln("Enter the ID of the Director: ")); - IO.println(DirectorService.findDirector(id).getName()); + 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().stream() + + "\n\nSeries:\n" + + d.getSeries().stream()); } private void updateDirector() { @@ -118,8 +143,6 @@ private void updateDirector() { } catch (NumberFormatException _) { } - //TODO: - //Determine which values aren't null, and update them Director updatedDirector = DirectorService.findDirector(id); if(name != null && !name.isEmpty()) updatedDirector.setName(name); @@ -129,7 +152,7 @@ private void updateDirector() { updatedDirector.setBirthYear(birthYear); if(yearOfDeath != null) updatedDirector.setYearOfDeath(yearOfDeath); - DirectorService.create(updatedDirector); + DirectorService.update(updatedDirector); } @@ -153,7 +176,7 @@ private void filmMenu() { //throws IOException, InterruptedException { case "2" -> listFilms(); case "3" -> listSpecificFilm(); case "4" -> updateFilm(); - case "5" -> mainMenu(em); + case "5" -> mainMenu(); default -> invalidInput(); } } @@ -162,22 +185,51 @@ private void createFilm() { //throws IOException, InterruptedException { //clearConsole(); String title = IO.readln("Enter the title of the Film: "); - //TODO: - //send information to create-method in org.example.Film class + try { + Film film = new Film(); + film.setTitle(title); + film.setDirector(directorService.findDirector(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(Film.findAll(em)); + IO.println(filmService.findAll().stream()); } private void listSpecificFilm() { - String title = IO.readln("Enter the title of the Film: "); - IO.println(Film.findByName(em, title)); + 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() { - String title = IO.readln("Enter the title of the Film: "); - Film.update(em, title); + try { + IO.println("When prompted, enter the value you wish to update." + + "If you don't want to change it, leave the input blank."); + Film film = filmService.findFilm(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.findDirector(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() { //throws IOException, InterruptedException { @@ -200,45 +252,85 @@ private void seriesMenu() { //throws IOException, InterruptedException { case "2" -> listSeries(); case "3" -> listSpecificSeries(); case "4" -> updateSeries(); - case "5" -> mainMenu(em); + case "5" -> mainMenu(); default -> invalidInput(); } } private void createSeries() { //throws IOException, InterruptedException { //clearConsole(); - 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 = Integer.valueOf(IO.readln("Enter the year the Series ended." + - "leave blank if not yet finished: ")); - String starActors = IO.readln("Enter the star actors of the Series: "); + 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 = Integer.valueOf(IO.readln("Enter the year the Series ended." + + "leave blank if not yet finished: ")); + 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); - //TODO: - //send information to create-method in Series class + } catch (NumberFormatException e) { + System.out.println("Invalid input!"); + } } private void listSeries() { - IO.println(Series.findAll(em)); + IO.println(seriesService.findAll().stream()); } private void listSpecificSeries() { - String title = IO.readln("Enter the title of the Series: "); - IO.println(Series.findByName(em, title)); + 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().stream() + + "\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." + "If you don't want to change it, leave the input blank."); - + Series series = new Series(); String title = IO.readln("Enter the title of the Series: "); - Integer episodes = Integer.valueOf(IO.readln("Enter the number of episodes in the Series: ")); - Integer firstAired = Integer.valueOf(IO.readln("Enter the year the Series was first released: ")); - Integer lastAired = Integer.valueOf(IO.readln("Enter the year the Series ended: ")); + 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); - //TODO: - //Determine which values aren't null, and update them + seriesService.update(series); } // private void clearConsole() throws IOException, InterruptedException { From 57b7d4e76a0a1f53e5c732066be97861f566ddb2 Mon Sep 17 00:00:00 2001 From: JohanHiths Date: Wed, 14 Jan 2026 09:17:00 +0100 Subject: [PATCH 32/41] Add files via upload --- src/main/java/org/example/BusinessException.java | 6 ++++++ src/main/java/org/example/Main.java | 7 +++---- 2 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/example/BusinessException.java 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/Main.java b/src/main/java/org/example/Main.java index 9185cc0b..02cb29e5 100644 --- a/src/main/java/org/example/Main.java +++ b/src/main/java/org/example/Main.java @@ -25,7 +25,7 @@ static void main() { try { - em.getTransaction().begin(); + DirectorRepositoryImpl directorRepository = new DirectorRepositoryImpl(emf); Director d = new Director(); d.setName("John Doe"); @@ -33,11 +33,10 @@ static void main() { directorRepository.save(d); em.getTransaction().commit(); - + } catch (Exception e) { System.err.println("Error: " + e.getMessage()); - } finally { - em.close(); + throw e; } }); From b043f5537240191da5aa1c4cccd446d862eea65d Mon Sep 17 00:00:00 2001 From: Edvin Sandgren <229709012+EdvinSandgren@users.noreply.github.com> Date: Wed, 14 Jan 2026 09:32:07 +0100 Subject: [PATCH 33/41] Implements fixes highlighted by CodeRabbit --- src/main/java/org/example/CLI.java | 36 +++++++++++++++++------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/example/CLI.java b/src/main/java/org/example/CLI.java index 353819d4..205ea5d1 100644 --- a/src/main/java/org/example/CLI.java +++ b/src/main/java/org/example/CLI.java @@ -44,7 +44,7 @@ void mainMenu() { //throws IOException, InterruptedException { private static void invalidInput() { System.out.println("Invalid input!" + - "PLease enter the number of the option you wish to choose"); + "\nPlease enter the number of the option you wish to choose"); } private void directorMenu() { //throws IOException, InterruptedException { @@ -84,7 +84,7 @@ private void createDirector() { //throws IOException, InterruptedException { 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." + - "If they're alive, leave blank: ")); + "\nIf they're alive, leave blank: ")); } catch (NumberFormatException _) { } @@ -105,7 +105,7 @@ private void listDirectors() { } private void listSpecificDirector() { - String input = IO.readln("Enter the ID or name of the Director: ")); + String input = IO.readln("Enter the ID or name of the Director: "); Director d; try{ d = directorService.findDirectorId(Long.valueOf(input)); @@ -119,16 +119,16 @@ private void listSpecificDirector() { "\nYear of birth: " + d.getBirthYear() + "\nYear of death: " + d.getYearOfDeath() + "Films:\n" + - d.getFilms().stream() + + d.getFilms() + "\n\nSeries:\n" + - d.getSeries().stream()); + 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." + - "If you don't want to change it, leave the input blank."); + "\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: "); @@ -143,7 +143,7 @@ private void updateDirector() { } catch (NumberFormatException _) { } - Director updatedDirector = DirectorService.findDirector(id); + Director updatedDirector = directorService.findDirector(id); if(name != null && !name.isEmpty()) updatedDirector.setName(name); if(country != null && !country.isEmpty()) @@ -152,7 +152,7 @@ private void updateDirector() { updatedDirector.setBirthYear(birthYear); if(yearOfDeath != null) updatedDirector.setYearOfDeath(yearOfDeath); - DirectorService.update(updatedDirector); + directorService.update(updatedDirector); } @@ -196,7 +196,7 @@ private void createFilm() { //throws IOException, InterruptedException { } private void listFilms() { - IO.println(filmService.findAll().stream()); + IO.println(filmService.findAll()); } private void listSpecificFilm() { @@ -215,7 +215,7 @@ private void listSpecificFilm() { private void updateFilm() { try { IO.println("When prompted, enter the value you wish to update." + - "If you don't want to change it, leave the input blank."); + "\nIf you don't want to change it, leave the input blank."); Film film = filmService.findFilm(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()) @@ -263,8 +263,12 @@ private void createSeries() { //throws IOException, InterruptedException { 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 = Integer.valueOf(IO.readln("Enter the year the Series ended." + - "leave blank if not yet finished: ")); + 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(); @@ -282,7 +286,7 @@ private void createSeries() { //throws IOException, InterruptedException { } private void listSeries() { - IO.println(seriesService.findAll().stream()); + IO.println(seriesService.findAll()); } private void listSpecificSeries() { @@ -296,7 +300,7 @@ private void listSpecificSeries() { } IO.println("Title: " + s.getTitle() + - "\nDirector: " + s.getDirectors().stream() + + "\nDirector: " + s.getDirectors() + "\nEpisodes: " + s.getEpisodes() + "\nFirst Aired: " + s.getFirstAired() + "\nLast Aired: " + s.getLastAired() + @@ -306,8 +310,8 @@ private void listSpecificSeries() { private void updateSeries() { IO.println("When prompted, enter the value you wish to update." + - "If you don't want to change it, leave the input blank."); - Series series = new Series(); + "\nIf you don't want to change it, leave the input blank."); + Series series = seriesService.findSeriesId(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); From e2f2c577df51882e11475227c53ff24dd3370a33 Mon Sep 17 00:00:00 2001 From: JohanHiths Date: Wed, 14 Jan 2026 09:33:28 +0100 Subject: [PATCH 34/41] Add files via upload --- src/main/java/org/example/Main.java | 37 ++++++--------------------- src/main/java/org/example/Series.java | 26 +++++++++---------- 2 files changed, 21 insertions(+), 42 deletions(-) diff --git a/src/main/java/org/example/Main.java b/src/main/java/org/example/Main.java index 02cb29e5..0fca7490 100644 --- a/src/main/java/org/example/Main.java +++ b/src/main/java/org/example/Main.java @@ -17,34 +17,13 @@ static void main() { .property("hibernate.highlight_sql", "true") .managedClasses(Film.class, Director.class, Series.class); - try (EntityManagerFactory emf = cfg.createEntityManagerFactory()) { - - emf.runInTransaction(em -> { - - - - - try { - - DirectorRepositoryImpl directorRepository = new DirectorRepositoryImpl(emf); - Director d = new Director(); - d.setName("John Doe"); - - directorRepository.save(d); - - em.getTransaction().commit(); - - } catch (Exception e) { - System.err.println("Error: " + e.getMessage()); - throw e; - } - - }); - - } + try (EntityManagerFactory emf = cfg.createEntityManagerFactory()) { + emf.runInTransaction(em -> { + DirectorRepositoryImpl directorRepository = new DirectorRepositoryImpl(emf); + Director d = new Director(); + d.setName("John Doe"); + directorRepository.save(d); + }); + } } - - - - } diff --git a/src/main/java/org/example/Series.java b/src/main/java/org/example/Series.java index 4d04926c..386a944b 100644 --- a/src/main/java/org/example/Series.java +++ b/src/main/java/org/example/Series.java @@ -8,7 +8,7 @@ @Entity public class Series extends BaseEntity{ - private Long id; + @ManyToMany (mappedBy = "series", cascade = { CascadeType.PERSIST, CascadeType.MERGE}) @@ -82,16 +82,16 @@ 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 id != null && id.equals(other.id); -// } -// -// @Override -// public int hashCode() { -// return 31; -// } + @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; + } } From ba087fbec111662344bbe5655a88e1439a5bd7de Mon Sep 17 00:00:00 2001 From: Mattias Barth Date: Wed, 14 Jan 2026 10:01:52 +0100 Subject: [PATCH 35/41] update BaseRepositoryImpl, Director, FilmRepositoryImpl and SeriesRepositoryImpl after CodeRabbit suggestions. --- src/main/java/org/example/BaseRepositoryImpl.java | 9 ++++++--- src/main/java/org/example/Director.java | 1 - src/main/java/org/example/FilmRepositoryImpl.java | 4 ++-- src/main/java/org/example/SeriesRepositoryImpl.java | 7 ++++++- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/example/BaseRepositoryImpl.java b/src/main/java/org/example/BaseRepositoryImpl.java index dfe622ac..e9c846b2 100644 --- a/src/main/java/org/example/BaseRepositoryImpl.java +++ b/src/main/java/org/example/BaseRepositoryImpl.java @@ -10,12 +10,15 @@ public class BaseRepositoryImpl implements Rep protected Class entityClass; -// public BaseRepositoryImpl(EntityManager em, Class entityClass) { -public BaseRepositoryImpl(Class entityClass) { - this.em = em; + public BaseRepositoryImpl(Class entityClass) { this.entityClass = entityClass; } + public void setEntityManager(EntityManager em) { + this.em = em; + } + + @Override public T save(T entity) { diff --git a/src/main/java/org/example/Director.java b/src/main/java/org/example/Director.java index be6420ea..66c316fa 100644 --- a/src/main/java/org/example/Director.java +++ b/src/main/java/org/example/Director.java @@ -1,7 +1,6 @@ package org.example; import jakarta.persistence.*; -import org.hibernate.engine.internal.Cascade; import java.util.HashSet; import java.util.Set; diff --git a/src/main/java/org/example/FilmRepositoryImpl.java b/src/main/java/org/example/FilmRepositoryImpl.java index f18ffe3e..fe9e5b29 100644 --- a/src/main/java/org/example/FilmRepositoryImpl.java +++ b/src/main/java/org/example/FilmRepositoryImpl.java @@ -6,8 +6,8 @@ public class FilmRepositoryImpl extends BaseRepositoryImpl implements FilmRepository { - public FilmRepositoryImpl(EntityManagerFactory em) { - super(em.createEntityManager(), Film.class); + public FilmRepositoryImpl() { + super(Film.class); } @Override diff --git a/src/main/java/org/example/SeriesRepositoryImpl.java b/src/main/java/org/example/SeriesRepositoryImpl.java index bdd6512d..2494ac64 100644 --- a/src/main/java/org/example/SeriesRepositoryImpl.java +++ b/src/main/java/org/example/SeriesRepositoryImpl.java @@ -6,9 +6,14 @@ public class SeriesRepositoryImpl extends BaseRepositoryImpl implements SeriesRepository { + private final EntityManagerFactory emf; + public SeriesRepositoryImpl(EntityManagerFactory em) { + super(Series.class); + this.emf = em; + } + - super(em.createEntityManager(), Series.class); } @Override From e91d463d56c07a3912c58cf89dec235e9d60fc9e Mon Sep 17 00:00:00 2001 From: Edvin Sandgren <229709012+EdvinSandgren@users.noreply.github.com> Date: Wed, 14 Jan 2026 10:42:20 +0100 Subject: [PATCH 36/41] Fixes various issues related to merges --- src/main/java/org/example/CLI.java | 33 +++++-------------- src/main/java/org/example/Director.java | 4 +++ .../java/org/example/DirectorService.java | 28 ++++++++-------- .../java/org/example/FilmRepositoryImpl.java | 5 ++- src/main/java/org/example/Main.java | 13 ++++++++ .../org/example/SeriesRepositoryImpl.java | 3 -- 6 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/main/java/org/example/CLI.java b/src/main/java/org/example/CLI.java index 205ea5d1..360627ce 100644 --- a/src/main/java/org/example/CLI.java +++ b/src/main/java/org/example/CLI.java @@ -1,9 +1,6 @@ package org.example; -import jakarta.persistence.EntityManager; - public class CLI { - //private final String os = System.getProperty("os.name"); DirectorService directorService; FilmService filmService; SeriesService seriesService; @@ -16,9 +13,8 @@ void cliStart(DirectorService directorService, FilmService filmService, SeriesSe mainMenu(); } - void mainMenu() { //throws IOException, InterruptedException { + void mainMenu() { while(true) { - //clearConsole(); System.out.println(""" Welcome to the Film Database! @@ -47,8 +43,7 @@ private static void invalidInput() { "\nPlease enter the number of the option you wish to choose"); } - private void directorMenu() { //throws IOException, InterruptedException { - //clearConsole(); + private void directorMenu() { System.out.println(""" You are in the Director Menu. @@ -72,8 +67,7 @@ private void directorMenu() { //throws IOException, InterruptedException { } } - private void createDirector() { //throws IOException, InterruptedException { - //clearConsole(); + private void createDirector() { String name; String country; int birthYear; @@ -101,7 +95,7 @@ private void createDirector() { //throws IOException, InterruptedException { } private void listDirectors() { - IO.println(directorService.findAllDirectors()); + IO.println(directorService.findAll()); } private void listSpecificDirector() { @@ -156,8 +150,7 @@ private void updateDirector() { } - private void filmMenu() { //throws IOException, InterruptedException { - //clearConsole(); + private void filmMenu() { System.out.println(""" You are in the Film Menu. @@ -181,8 +174,7 @@ private void filmMenu() { //throws IOException, InterruptedException { } } - private void createFilm() { //throws IOException, InterruptedException { - //clearConsole(); + private void createFilm() { String title = IO.readln("Enter the title of the Film: "); try { @@ -232,8 +224,7 @@ private void updateFilm() { } } - private void seriesMenu() { //throws IOException, InterruptedException { - //clearConsole(); + private void seriesMenu() { System.out.println(""" You are in the Series Menu. @@ -257,8 +248,7 @@ private void seriesMenu() { //throws IOException, InterruptedException { } } - private void createSeries() { //throws IOException, InterruptedException { - //clearConsole(); + 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: ")); @@ -337,11 +327,4 @@ private void updateSeries() { seriesService.update(series); } -// private void clearConsole() throws IOException, InterruptedException { -// if(os.contains("Windows")) -// new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor(); -// else -// new ProcessBuilder("clear").inheritIO().start().waitFor(); -// } - } diff --git a/src/main/java/org/example/Director.java b/src/main/java/org/example/Director.java index 66c316fa..a819decb 100644 --- a/src/main/java/org/example/Director.java +++ b/src/main/java/org/example/Director.java @@ -38,6 +38,10 @@ public class Director extends BaseEntity{ + public Set getSeries() { + return series; + } + public Set getFilms() { return films; } diff --git a/src/main/java/org/example/DirectorService.java b/src/main/java/org/example/DirectorService.java index 85a34fb3..7a4b37d0 100644 --- a/src/main/java/org/example/DirectorService.java +++ b/src/main/java/org/example/DirectorService.java @@ -24,20 +24,20 @@ public void addFilm(Long directorId, Film film) { directorRepository.save(director); } - public Director update(Long id, 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); - } - return directorRepository.save(existingDirector); + 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); } diff --git a/src/main/java/org/example/FilmRepositoryImpl.java b/src/main/java/org/example/FilmRepositoryImpl.java index fe9e5b29..8933eff4 100644 --- a/src/main/java/org/example/FilmRepositoryImpl.java +++ b/src/main/java/org/example/FilmRepositoryImpl.java @@ -6,8 +6,11 @@ public class FilmRepositoryImpl extends BaseRepositoryImpl implements FilmRepository { - public FilmRepositoryImpl() { + private final EntityManagerFactory emf; + + public FilmRepositoryImpl(EntityManagerFactory em) { super(Film.class); + this.emf = em; } @Override diff --git a/src/main/java/org/example/Main.java b/src/main/java/org/example/Main.java index de3db276..feef9707 100644 --- a/src/main/java/org/example/Main.java +++ b/src/main/java/org/example/Main.java @@ -24,6 +24,19 @@ public static void main(String[] args) { d.setName("John Doe"); directorRepository.save(d); }); + + DirectorRepositoryImpl directorRepository = new DirectorRepositoryImpl(emf); + DirectorService directorService = new DirectorService(directorRepository); + + FilmRepositoryImpl filmRepository = new FilmRepositoryImpl(emf); + 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/SeriesRepositoryImpl.java b/src/main/java/org/example/SeriesRepositoryImpl.java index 2494ac64..51d7e311 100644 --- a/src/main/java/org/example/SeriesRepositoryImpl.java +++ b/src/main/java/org/example/SeriesRepositoryImpl.java @@ -13,9 +13,6 @@ public SeriesRepositoryImpl(EntityManagerFactory em) { this.emf = em; } - - } - @Override public Optional findByName(String title){ return em.createQuery("SELECT s FROM Series s WHERE s.title = :title", Series.class) From e9fb1ae7bf31408cbf5624f38c23afecb4e6908b Mon Sep 17 00:00:00 2001 From: Edvin Sandgren <229709012+EdvinSandgren@users.noreply.github.com> Date: Wed, 14 Jan 2026 10:55:37 +0100 Subject: [PATCH 37/41] Fixes minor issues identified by CodeRabbit --- src/main/java/org/example/CLI.java | 47 ++++++++++++++++------------- src/main/java/org/example/Main.java | 8 +++-- 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/src/main/java/org/example/CLI.java b/src/main/java/org/example/CLI.java index 360627ce..906e5d40 100644 --- a/src/main/java/org/example/CLI.java +++ b/src/main/java/org/example/CLI.java @@ -301,30 +301,35 @@ private void listSpecificSeries() { 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."); - Series series = seriesService.findSeriesId(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 _) { + 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!"); } - String starActors = IO.readln("Enter the star actors of the Series: "); - if (starActors != null && !starActors.isEmpty()) - series.setStarActors(starActors); - seriesService.update(series); } } diff --git a/src/main/java/org/example/Main.java b/src/main/java/org/example/Main.java index feef9707..99a5d7c7 100644 --- a/src/main/java/org/example/Main.java +++ b/src/main/java/org/example/Main.java @@ -20,9 +20,11 @@ public static void main(String[] args) { try (EntityManagerFactory emf = cfg.createEntityManagerFactory()) { emf.runInTransaction(em -> { DirectorRepositoryImpl directorRepository = new DirectorRepositoryImpl(emf); - Director d = new Director(); - d.setName("John Doe"); - directorRepository.save(d); + if (!directorRepository.findAll().iterator().hasNext()) { + Director d = new Director(); + d.setName("John Doe"); + directorRepository.save(d); + } }); DirectorRepositoryImpl directorRepository = new DirectorRepositoryImpl(emf); From 4929c8fcfd3ee3a6807aac540c8a0049f8072026 Mon Sep 17 00:00:00 2001 From: Edvin Sandgren <229709012+EdvinSandgren@users.noreply.github.com> Date: Wed, 14 Jan 2026 11:12:57 +0100 Subject: [PATCH 38/41] Adds some missing methods and changes a few field names --- src/main/java/org/example/CLI.java | 8 ++++---- src/main/java/org/example/DirectorService.java | 11 ++++++++++- src/main/java/org/example/FilmService.java | 14 +++++++++----- src/main/java/org/example/SeriesRepository.java | 2 +- .../java/org/example/SeriesRepositoryImpl.java | 2 +- src/main/java/org/example/SeriesService.java | 14 +++++++++----- 6 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/main/java/org/example/CLI.java b/src/main/java/org/example/CLI.java index 906e5d40..5f672d02 100644 --- a/src/main/java/org/example/CLI.java +++ b/src/main/java/org/example/CLI.java @@ -137,7 +137,7 @@ private void updateDirector() { } catch (NumberFormatException _) { } - Director updatedDirector = directorService.findDirector(id); + Director updatedDirector = directorService.findDirectorId(id); if(name != null && !name.isEmpty()) updatedDirector.setName(name); if(country != null && !country.isEmpty()) @@ -180,7 +180,7 @@ private void createFilm() { try { Film film = new Film(); film.setTitle(title); - film.setDirector(directorService.findDirector(Long.valueOf(IO.readln("Enter the ID of the Director: ")))); + 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!"); @@ -208,12 +208,12 @@ 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.findFilm(Long.valueOf(IO.readln("Enter the ID of the Film: "))); + 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.findDirector(Long.valueOf(IO.readln("Enter the ID of the Director: "))); + Director director = directorService.findDirectorId(Long.valueOf(IO.readln("Enter the ID of the Director: "))); film.setDirector(director); } catch (NumberFormatException _) { } diff --git a/src/main/java/org/example/DirectorService.java b/src/main/java/org/example/DirectorService.java index 7a4b37d0..84a08d54 100644 --- a/src/main/java/org/example/DirectorService.java +++ b/src/main/java/org/example/DirectorService.java @@ -54,7 +54,7 @@ public void delete(Long id) { directorRepository.delete(director); } - public Director findDirector(Long id) { + public Director findDirectorId(Long id) { //Old code // Director director = (Director) directorRepository.findById(id) // .orElseThrow(); @@ -64,7 +64,16 @@ public Director findDirector(Long id) { 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())) diff --git a/src/main/java/org/example/FilmService.java b/src/main/java/org/example/FilmService.java index e5868c16..25084630 100644 --- a/src/main/java/org/example/FilmService.java +++ b/src/main/java/org/example/FilmService.java @@ -16,14 +16,18 @@ public void update(Film film) { filmRepository.save(film); } - public FilmDTO find(Long id) { - return filmRepository.findById(id) - .map(f -> new FilmDTO(f.getTitle())) - .orElseThrow(() -> new RuntimeException("Film not found: " + id)); + public Iterable findAll() { + return filmRepository.findAll(); + } - public Film findFilm(Long id) { + 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/SeriesRepository.java b/src/main/java/org/example/SeriesRepository.java index 8a0e8ef2..5ff45a84 100644 --- a/src/main/java/org/example/SeriesRepository.java +++ b/src/main/java/org/example/SeriesRepository.java @@ -3,5 +3,5 @@ import java.util.Optional; public interface SeriesRepository extends Repository { - Optional findByName(String name); + Optional findByTitle(String title); } diff --git a/src/main/java/org/example/SeriesRepositoryImpl.java b/src/main/java/org/example/SeriesRepositoryImpl.java index 51d7e311..aea28463 100644 --- a/src/main/java/org/example/SeriesRepositoryImpl.java +++ b/src/main/java/org/example/SeriesRepositoryImpl.java @@ -14,7 +14,7 @@ public SeriesRepositoryImpl(EntityManagerFactory em) { } @Override - public Optional findByName(String title){ + public Optional findByTitle(String title){ return em.createQuery("SELECT s FROM Series s WHERE s.title = :title", Series.class) .setParameter("title", title) .getResultStream() diff --git a/src/main/java/org/example/SeriesService.java b/src/main/java/org/example/SeriesService.java index 47be1ada..93784fa8 100644 --- a/src/main/java/org/example/SeriesService.java +++ b/src/main/java/org/example/SeriesService.java @@ -23,14 +23,18 @@ public void update(Series series) { seriesRepository.save(series); } - public SeriesDTO find(Long id) { - return seriesRepository.findById(id) - .map(SeriesDTO::new) - .orElseThrow(() -> new RuntimeException("Series not found: " + id)); + public Iterable findAll() { + return seriesRepository.findAll(); + } - public Series findSeries(Long id) { + 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)); + } } From af124544d6b2f6446386bb542cc3bb6595c6e49e Mon Sep 17 00:00:00 2001 From: JohanHiths Date: Wed, 14 Jan 2026 17:04:00 +0100 Subject: [PATCH 39/41] Add files via upload --- src/main/java/org/example/Main.java | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/example/Main.java b/src/main/java/org/example/Main.java index 0fca7490..ed2e5234 100644 --- a/src/main/java/org/example/Main.java +++ b/src/main/java/org/example/Main.java @@ -19,11 +19,24 @@ static void main() { try (EntityManagerFactory emf = cfg.createEntityManagerFactory()) { emf.runInTransaction(em -> { - DirectorRepositoryImpl directorRepository = new DirectorRepositoryImpl(emf); - Director d = new Director(); - d.setName("John Doe"); - directorRepository.save(d); + 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); } } From cff7dee12569490de2871d648f572afd8b19987a Mon Sep 17 00:00:00 2001 From: JohanHiths Date: Wed, 14 Jan 2026 17:12:51 +0100 Subject: [PATCH 40/41] Add files via upload From 5dff5c614ac6f2d375f78dd44ee67ee36de02d13 Mon Sep 17 00:00:00 2001 From: JohanHiths Date: Wed, 14 Jan 2026 17:29:35 +0100 Subject: [PATCH 41/41] Add files via upload --- src/main/java/org/example/Main.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/example/Main.java b/src/main/java/org/example/Main.java index 0ff6922c..ed2e5234 100644 --- a/src/main/java/org/example/Main.java +++ b/src/main/java/org/example/Main.java @@ -4,7 +4,7 @@ import org.hibernate.jpa.HibernatePersistenceConfiguration; public class Main { - public static void main(String[] args) { + static void main() { final PersistenceConfiguration cfg = new HibernatePersistenceConfiguration("emf")