diff --git a/src/main/java/edu/hsh/dbs2/imdb/entity/Movie.java b/src/main/java/edu/hsh/dbs2/imdb/entity/Movie.java index cdde9ad3db73e3ba8370bcd93418991df5fb4bb7..c81c011592f2471f1d251c1944393d46d8135be8 100644 --- a/src/main/java/edu/hsh/dbs2/imdb/entity/Movie.java +++ b/src/main/java/edu/hsh/dbs2/imdb/entity/Movie.java @@ -32,10 +32,10 @@ public class Movie { @Enumerated(EnumType.STRING) private MovieType type; - @OneToMany(cascade = CascadeType.ALL, mappedBy = "movie", fetch = FetchType.EAGER) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "movie", fetch = FetchType.EAGER, orphanRemoval = true) private Set<MovieCharacter> characters; - @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.MERGE) + @ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE}, targetEntity = Genre.class) @JoinTable(name = "MovieGenre", joinColumns = @JoinColumn(name = "MovieID"), inverseJoinColumns = @JoinColumn(name = "GenreID")) private Set<Genre> genres; diff --git a/src/main/java/edu/hsh/dbs2/imdb/entity/MovieCharacter.java b/src/main/java/edu/hsh/dbs2/imdb/entity/MovieCharacter.java index e86318f6b03a0920224a3f2c41ea84085a3496c1..de5fa5e0d57b81551e6201493ecfd93bf261ac3f 100644 --- a/src/main/java/edu/hsh/dbs2/imdb/entity/MovieCharacter.java +++ b/src/main/java/edu/hsh/dbs2/imdb/entity/MovieCharacter.java @@ -29,7 +29,7 @@ public class MovieCharacter { @Column(name = "Position") private Integer position; - @ManyToOne(cascade = CascadeType.MERGE) + @ManyToOne(cascade = {CascadeType.MERGE}) @JoinColumn(name = "Actor") private Person actor; diff --git a/src/main/java/edu/hsh/dbs2/imdb/logic/Manager.java b/src/main/java/edu/hsh/dbs2/imdb/logic/Manager.java index 87d91efc000e91634afc5ac6e806d8a55a31e2f7..649e7d185540110780afca2aaac5667835543781 100644 --- a/src/main/java/edu/hsh/dbs2/imdb/logic/Manager.java +++ b/src/main/java/edu/hsh/dbs2/imdb/logic/Manager.java @@ -8,6 +8,7 @@ import jakarta.persistence.criteria.CriteriaQuery; import java.lang.reflect.ParameterizedType; import java.util.List; +import java.util.Optional; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -22,15 +23,12 @@ public class Manager<T> { this.type = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; } - protected List<T> queryNoClose(BiConsumer<CriteriaBuilder, CriteriaQuery<T>> function) { + protected List<T> query(BiConsumer<CriteriaBuilder, CriteriaQuery<T>> function) { var manager = getEntityManager(); var cb = manager.getCriteriaBuilder(); var cq = cb.createQuery(type); function.accept(cb, cq); - return manager.createQuery(cq).getResultList(); - } - protected List<T> query(BiConsumer<CriteriaBuilder, CriteriaQuery<T>> function) { - var result = queryNoClose(function); + var result = manager.createQuery(cq).getResultList(); closeEntityManager(); return result; } @@ -61,9 +59,16 @@ public class Manager<T> { protected <E> E mergeIfDetached(E entity) { var manager = getEntityManager(); - if (!manager.contains(entity)) + if (!manager.contains(entity)) { return manager.merge(entity); + } return entity; } + protected Optional<T> find(Object id) { + if (id == null) + return Optional.empty(); + return Optional.ofNullable(getEntityManager().find(type, id)); + } + } diff --git a/src/main/java/edu/hsh/dbs2/imdb/logic/MovieManager.java b/src/main/java/edu/hsh/dbs2/imdb/logic/MovieManager.java index 6015352f51cdc4bf49386aa2f42ef72ad097cacd..05723d74ac9c0f95d8f17e83a5bec0320a7245c7 100644 --- a/src/main/java/edu/hsh/dbs2/imdb/logic/MovieManager.java +++ b/src/main/java/edu/hsh/dbs2/imdb/logic/MovieManager.java @@ -31,13 +31,15 @@ public class MovieManager extends Manager<Movie> { return movies.stream().map(mapper::map).collect(Collectors.toList()); } - public void insertUpdateMovie(final MovieDTO movieDTO) { - Optional<Movie> movie = movieDTO.getId() == null ? Optional.empty() : findMovieById(movieDTO.getId()); + public void insertUpdateMovie(final MovieDTO dto) { + if (dto == null) + return; + Optional<Movie> movie = find(dto.getId()); updateMapper(); if (movie.isPresent()) - update(movie.get(), movieDTO); + update(movie.get(), dto); else - insert(movieDTO); + insert(dto); closeEntityManager(); } @@ -53,11 +55,15 @@ public class MovieManager extends Manager<Movie> { } private void update(Movie movie, MovieDTO dto) { - doTransaction(manager -> mapper.deepUnmapOn(dto, mergeIfDetached(movie))); + doTransaction(manager -> { + manager.detach(movie); + mapper.deepUnmapOn(dto, movie); + manager.merge(movie); + }); } public void deleteMovie(final long movieId) { - var movie = findMovieById(movieId); + var movie = find(movieId); movie.ifPresent(this::delete); closeEntityManager(); } @@ -67,16 +73,9 @@ public class MovieManager extends Manager<Movie> { } public MovieDTO getMovie(final long movieId) { - var movie = findMovieById(movieId); + var movie = find(movieId); closeEntityManager(); return movie.map(mapper::map).orElse(null); } - private Optional<Movie> findMovieById(final long id) { - return queryNoClose((cb, cq) -> { - var root = cq.from(Movie.class); - cq.select(root).where(cb.equal(root.get("id"), id)); - }).stream().findAny(); - } - } diff --git a/src/test/java/edu/hsh/dbs2/imdb/TestDB.java b/src/test/java/edu/hsh/dbs2/imdb/TestDB.java index b96fa615c10f984731b792152301e510adc8cc39..f1898bc2af1421e6b6f74cd29b6d08b9eba4016a 100644 --- a/src/test/java/edu/hsh/dbs2/imdb/TestDB.java +++ b/src/test/java/edu/hsh/dbs2/imdb/TestDB.java @@ -128,6 +128,7 @@ public class TestDB { assertEquals(newCharacter.getAlias(), sameCharacter.getAlias()); assertEquals(newCharacter.getPlayer(), sameCharacter.getPlayer()); characters.remove(sameCharacter); + assertEquals(1, characters.size()); movieManager.insertUpdateMovie(after); after = movieManager.getMovie(1); characters = after.getCharacters();