Skip to content
Snippets Groups Projects
Commit b04913a3 authored by opitzju's avatar opitzju
Browse files

gröbste Fehler behoben

parent 42e76463
No related branches found
No related tags found
No related merge requests found
Showing
with 139 additions and 51 deletions
...@@ -4,7 +4,6 @@ import edu.hsh.dbs2.imdb.gui.SearchMovieDialog; ...@@ -4,7 +4,6 @@ import edu.hsh.dbs2.imdb.gui.SearchMovieDialog;
import edu.hsh.dbs2.imdb.gui.SearchMovieDialogCallback; import edu.hsh.dbs2.imdb.gui.SearchMovieDialogCallback;
import edu.hsh.dbs2.imdb.logic.ManagerFactory; import edu.hsh.dbs2.imdb.logic.ManagerFactory;
import edu.hsh.dbs2.imdb.util.EntityManagerFactoryUtil; import edu.hsh.dbs2.imdb.util.EntityManagerFactoryUtil;
import jakarta.persistence.Persistence;
import javax.swing.*; import javax.swing.*;
...@@ -17,12 +16,7 @@ public class Starter { ...@@ -17,12 +16,7 @@ public class Starter {
public static void main(String[] args) throws Throwable { public static void main(String[] args) throws Throwable {
ManagerFactory.instance.setSessionFactory(EntityManagerFactoryUtil.createSessionFactory()); ManagerFactory.instance.setSessionFactory(EntityManagerFactoryUtil.createSessionFactory());
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(() -> new Starter().run());
@Override
public void run() {
new Starter().run();
}
});
} }
......
...@@ -34,11 +34,9 @@ public class CharacterMapper implements Mapper<MovieCharacter, CharacterDTO> { ...@@ -34,11 +34,9 @@ public class CharacterMapper implements Mapper<MovieCharacter, CharacterDTO> {
} }
public MovieCharacter unmapOn(CharacterDTO dto, MovieCharacter character) { public MovieCharacter unmapOn(CharacterDTO dto, MovieCharacter character) {
if (people == null || people.isEmpty())
throw new IllegalStateException("CharacterMapper.unmapOn was called without first setting people.");
character.setCharacter(dto.getCharacter()); character.setCharacter(dto.getCharacter());
character.setAlias(dto.getAlias()); character.setAlias(dto.getAlias());
var person = people.stream().filter(p -> p.getName().equals(dto.getCharacter())).findAny().orElseThrow(); var person = character.getCharacter() == null ? null : people.stream().filter(p -> p.getName().equals(dto.getPlayer())).findAny().orElseThrow();
character.setActor(person); character.setActor(person);
return character; return character;
} }
......
package edu.hsh.dbs2.imdb.entity; package edu.hsh.dbs2.imdb.entity;
import jakarta.persistence.*;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import jakarta.persistence.*;
import java.util.Set;
@Getter @Getter
@Setter @Setter
@EqualsAndHashCode(onlyExplicitlyIncluded = true) @EqualsAndHashCode(onlyExplicitlyIncluded = true)
......
...@@ -12,8 +12,6 @@ public interface Mapper<T, E> { ...@@ -12,8 +12,6 @@ public interface Mapper<T, E> {
return ts.stream().map(this::map).collect(Collectors.toSet()); return ts.stream().map(this::map).collect(Collectors.toSet());
} }
default Set<T> unmapAll(Collection<E> es) { default Set<T> unmapAll(Collection<E> es) {
return es.stream().map(this::unmap).collect(Collectors.toSet()); return es.stream().map(this::unmap).collect(Collectors.toSet());
} }
......
...@@ -32,10 +32,10 @@ public class Movie { ...@@ -32,10 +32,10 @@ public class Movie {
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
private MovieType type; private MovieType type;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "movie") @OneToMany(cascade = CascadeType.ALL, mappedBy = "movie", fetch = FetchType.EAGER)
private Set<MovieCharacter> characters; private Set<MovieCharacter> characters;
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
@JoinTable(name = "MovieGenre", joinColumns = @JoinColumn(name = "MovieID"), @JoinTable(name = "MovieGenre", joinColumns = @JoinColumn(name = "MovieID"),
inverseJoinColumns = @JoinColumn(name = "GenreID")) inverseJoinColumns = @JoinColumn(name = "GenreID"))
private Set<Genre> genres; private Set<Genre> genres;
......
...@@ -29,7 +29,7 @@ public class MovieCharacter { ...@@ -29,7 +29,7 @@ public class MovieCharacter {
@Column(name = "Position") @Column(name = "Position")
private Integer position; private Integer position;
@ManyToOne @ManyToOne(cascade = CascadeType.MERGE)
@JoinColumn(name = "Actor") @JoinColumn(name = "Actor")
private Person actor; private Person actor;
......
...@@ -2,7 +2,9 @@ package edu.hsh.dbs2.imdb.entity; ...@@ -2,7 +2,9 @@ package edu.hsh.dbs2.imdb.entity;
import edu.hsh.dbs2.imdb.logic.dto.CharacterDTO; import edu.hsh.dbs2.imdb.logic.dto.CharacterDTO;
import edu.hsh.dbs2.imdb.logic.dto.MovieDTO; import edu.hsh.dbs2.imdb.logic.dto.MovieDTO;
import edu.hsh.dbs2.imdb.util.NullTolerantMapCollector;
import edu.hsh.dbs2.imdb.util.Pair; import edu.hsh.dbs2.imdb.util.Pair;
import edu.hsh.dbs2.imdb.util.Util;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
...@@ -49,7 +51,7 @@ public class MovieMapper implements Mapper<Movie, MovieDTO> { ...@@ -49,7 +51,7 @@ public class MovieMapper implements Mapper<Movie, MovieDTO> {
} }
public Movie unmapOn(MovieDTO dto, Movie movie) { public Movie unmapOn(MovieDTO dto, Movie movie) {
if (genres == null || genres.isEmpty()) if (genres == null && !Util.isNullOrEmpty(dto.getGenres()))
throw new IllegalStateException("MovieMapper.unmapOn was called without first setting genres."); throw new IllegalStateException("MovieMapper.unmapOn was called without first setting genres.");
movie.setTitle(dto.getTitle()); movie.setTitle(dto.getTitle());
movie.setYear(dto.getYear()); movie.setYear(dto.getYear());
...@@ -64,6 +66,7 @@ public class MovieMapper implements Mapper<Movie, MovieDTO> { ...@@ -64,6 +66,7 @@ public class MovieMapper implements Mapper<Movie, MovieDTO> {
public Movie deepUnmapOn(MovieDTO dto, Movie movie) { public Movie deepUnmapOn(MovieDTO dto, Movie movie) {
unmapOn(dto, movie); unmapOn(dto, movie);
charMapper.setMovie(movie);
var mapping = mapMatchingDropDeleted(dto.getCharacters(), movie.getCharacters()); var mapping = mapMatchingDropDeleted(dto.getCharacters(), movie.getCharacters());
var newCharacters = mapping.entrySet().stream() var newCharacters = mapping.entrySet().stream()
.map(insertOrUpdate(charMapper::unmap, charMapper::unmapOn)) .map(insertOrUpdate(charMapper::unmap, charMapper::unmapOn))
...@@ -91,7 +94,7 @@ public class MovieMapper implements Mapper<Movie, MovieDTO> { ...@@ -91,7 +94,7 @@ public class MovieMapper implements Mapper<Movie, MovieDTO> {
private Map<CharacterDTO, MovieCharacter> mapMatchingDropDeleted(List<CharacterDTO> dtos, Set<MovieCharacter> characters) { private Map<CharacterDTO, MovieCharacter> mapMatchingDropDeleted(List<CharacterDTO> dtos, Set<MovieCharacter> characters) {
return dtos.stream() return dtos.stream()
.map(dto -> matchMCharToDto(dto, characters)) .map(dto -> matchMCharToDto(dto, characters))
.collect(Collectors.toMap(Pair::getKey, Pair::getValue)); .collect(NullTolerantMapCollector.getCharacterMapper());
} }
private Pair<CharacterDTO, MovieCharacter> matchMCharToDto(CharacterDTO dto, Set<MovieCharacter> characters) { private Pair<CharacterDTO, MovieCharacter> matchMCharToDto(CharacterDTO dto, Set<MovieCharacter> characters) {
...@@ -100,4 +103,9 @@ public class MovieMapper implements Mapper<Movie, MovieDTO> { ...@@ -100,4 +103,9 @@ public class MovieMapper implements Mapper<Movie, MovieDTO> {
.findAny(); .findAny();
return new Pair<>(dto, matching.orElse(null)); return new Pair<>(dto, matching.orElse(null));
} }
public void update(Set<Genre> genres, Set<Person> people) {
setGenres(genres);
charMapper.setPeople(people);
}
} }
package edu.hsh.dbs2.imdb.entity; package edu.hsh.dbs2.imdb.entity;
import java.util.Arrays;
public enum MovieType { public enum MovieType {
V, T, C, G; V, T, C, G;
......
package edu.hsh.dbs2.imdb.entity; package edu.hsh.dbs2.imdb.entity;
import java.util.Arrays;
public enum Sex { public enum Sex {
f, m; f, m;
......
...@@ -24,7 +24,7 @@ public class GenreManager extends Manager { ...@@ -24,7 +24,7 @@ public class GenreManager extends Manager {
} }
Stream<Genre> getGenreImpl() { Stream<Genre> getGenreImpl() {
return query(Genre.class, (cb, cq) -> cq.select(cq.from(Genre.class))); return query(Genre.class, (cb, cq) -> cq.select(cq.from(Genre.class))).stream();
} }
} }
...@@ -5,8 +5,8 @@ import jakarta.persistence.criteria.CriteriaBuilder; ...@@ -5,8 +5,8 @@ import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.CriteriaQuery;
import lombok.Cleanup; import lombok.Cleanup;
import java.util.List;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.stream.Stream;
public class Manager { public class Manager {
protected final EntityManagerFactory sessionFactory; protected final EntityManagerFactory sessionFactory;
...@@ -15,11 +15,11 @@ public class Manager { ...@@ -15,11 +15,11 @@ public class Manager {
this.sessionFactory = sessionFactory; this.sessionFactory = sessionFactory;
} }
protected <T> Stream<T> query(Class<T> type, BiConsumer<CriteriaBuilder, CriteriaQuery<T>> function) { protected <T> List<T> query(Class<T> type, BiConsumer<CriteriaBuilder, CriteriaQuery<T>> function) {
@Cleanup var entityManager = sessionFactory.createEntityManager(); @Cleanup var entityManager = sessionFactory.createEntityManager();
var cb = entityManager.getCriteriaBuilder(); var cb = entityManager.getCriteriaBuilder();
var cq = cb.createQuery(type); var cq = cb.createQuery(type);
function.accept(cb, cq); function.accept(cb, cq);
return entityManager.createQuery(cq).getResultStream(); return entityManager.createQuery(cq).getResultList();
} }
} }
package edu.hsh.dbs2.imdb.logic; package edu.hsh.dbs2.imdb.logic;
import edu.hsh.dbs2.imdb.entity.*; import edu.hsh.dbs2.imdb.entity.Movie;
import edu.hsh.dbs2.imdb.logic.dto.CharacterDTO; import edu.hsh.dbs2.imdb.entity.MovieMapper;
import edu.hsh.dbs2.imdb.logic.dto.MovieDTO; import edu.hsh.dbs2.imdb.logic.dto.MovieDTO;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.EntityManagerFactory;
import lombok.Cleanup; import lombok.Cleanup;
import java.util.*; import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class MovieManager extends Manager { public class MovieManager extends Manager {
...@@ -35,7 +37,7 @@ public class MovieManager extends Manager { ...@@ -35,7 +37,7 @@ public class MovieManager extends Manager {
if (search != null && search.length() > 0) if (search != null && search.length() > 0)
cq.where(cb.like(cb.upper(root.get("title")), "%" + search.toUpperCase() + "%")); cq.where(cb.like(cb.upper(root.get("title")), "%" + search.toUpperCase() + "%"));
}); });
return movies.map(mapper::map).collect(Collectors.toList()); return movies.stream().map(mapper::map).collect(Collectors.toList());
} }
/** /**
...@@ -48,7 +50,7 @@ public class MovieManager extends Manager { ...@@ -48,7 +50,7 @@ public class MovieManager extends Manager {
* @throws Exception * @throws Exception
*/ */
public void insertUpdateMovie(final MovieDTO movieDTO) throws Exception { public void insertUpdateMovie(final MovieDTO movieDTO) throws Exception {
var movie = findMovieById(movieDTO.getId()); Optional<Movie> movie = movieDTO.getId() == null ? Optional.empty() : findMovieById(movieDTO.getId());
updateMapper(); updateMapper();
if (movie.isPresent()) if (movie.isPresent())
update(movie.get(), movieDTO); update(movie.get(), movieDTO);
...@@ -59,25 +61,31 @@ public class MovieManager extends Manager { ...@@ -59,25 +61,31 @@ public class MovieManager extends Manager {
private void updateMapper() { private void updateMapper() {
var genres = genreManager.getGenreImpl().collect(Collectors.toSet()); var genres = genreManager.getGenreImpl().collect(Collectors.toSet());
var people = personManager.getPeopleImpl(null).collect(Collectors.toSet()); var people = personManager.getPeopleImpl(null).collect(Collectors.toSet());
mapper.setGenres(genres); mapper.update(genres, people);
mapper.getCharMapper().setPeople(people);
} }
private void insert(MovieDTO dto) throws Exception { private void insert(MovieDTO dto) throws Exception {
var entityManager = sessionFactory.createEntityManager(); @Cleanup var entityManager = sessionFactory.createEntityManager();
var movie = mapper.unmap(dto);
entityManager.getTransaction().begin(); entityManager.getTransaction().begin();
var movie = mapper.unmap(dto);
entityManager.persist(movie); entityManager.persist(movie);
entityManager.getTransaction().commit(); entityManager.getTransaction().commit();
} }
private void update(Movie movie, MovieDTO dto) { private void update(Movie movie, MovieDTO dto) {
var entityManager = sessionFactory.createEntityManager(); @Cleanup var entityManager = sessionFactory.createEntityManager();
entityManager.getTransaction().begin(); entityManager.getTransaction().begin();
movie = mergeIfDetached(movie, entityManager);
mapper.deepUnmapOn(dto, movie); mapper.deepUnmapOn(dto, movie);
entityManager.getTransaction().commit(); entityManager.getTransaction().commit();
} }
private Movie mergeIfDetached(Movie movie, EntityManager entityManager) {
if (!entityManager.contains(movie))
return entityManager.merge(movie);
return movie;
}
/** /**
* Loescht einen Film aus der Datenbank. Es werden auch alle abhaengigen Objekte geloescht, * Loescht einen Film aus der Datenbank. Es werden auch alle abhaengigen Objekte geloescht,
* d.h. alle Charaktere und alle Genre-Zuordnungen. * d.h. alle Charaktere und alle Genre-Zuordnungen.
...@@ -94,6 +102,7 @@ public class MovieManager extends Manager { ...@@ -94,6 +102,7 @@ public class MovieManager extends Manager {
return; return;
@Cleanup var entityManager = sessionFactory.createEntityManager(); @Cleanup var entityManager = sessionFactory.createEntityManager();
entityManager.getTransaction().begin(); entityManager.getTransaction().begin();
movie = mergeIfDetached(movie, entityManager);
entityManager.remove(movie); entityManager.remove(movie);
entityManager.getTransaction().commit(); entityManager.getTransaction().commit();
} }
...@@ -113,7 +122,7 @@ public class MovieManager extends Manager { ...@@ -113,7 +122,7 @@ public class MovieManager extends Manager {
return query(Movie.class, (cb, cq) -> { return query(Movie.class, (cb, cq) -> {
var root = cq.from(Movie.class); var root = cq.from(Movie.class);
cq.select(root).where(cb.equal(root.get("id"), id)); cq.select(root).where(cb.equal(root.get("id"), id));
}).findAny(); }).stream().findAny();
} }
} }
...@@ -30,6 +30,6 @@ public class PersonManager extends Manager { ...@@ -30,6 +30,6 @@ public class PersonManager extends Manager {
cq.select(root); cq.select(root);
if (text != null && text.length() > 0) if (text != null && text.length() > 0)
cq.where(cb.like(root.get("name"), "%" + text + "%")); cq.where(cb.like(root.get("name"), "%" + text + "%"));
}); }).stream();
} }
} }
package edu.hsh.dbs2.imdb.util; package edu.hsh.dbs2.imdb.util;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence; import jakarta.persistence.Persistence;
import java.sql.Connection;
import java.sql.DriverManager;
public class EntityManagerFactoryUtil { public class EntityManagerFactoryUtil {
public static EntityManagerFactory createSessionFactory() { public static EntityManagerFactory createSessionFactory() {
try { try {
return Persistence.createEntityManagerFactory("edu.hsh.dbs2.imdb"); return Persistence.createEntityManagerFactory("edu.hsh.dbs2.imdb", Util.getTestDataProperty());
} catch (Exception e) { } catch (Exception e) {
System.err.println("Error while connecting to database"); System.err.println("Error while connecting to database");
e.printStackTrace(); e.printStackTrace();
......
package edu.hsh.dbs2.imdb.util;
import edu.hsh.dbs2.imdb.entity.MovieCharacter;
import edu.hsh.dbs2.imdb.logic.dto.CharacterDTO;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
public class NullTolerantMapCollector<T, E> implements Collector<Pair<T, E>, Map<T, E>, Map<T, E>> {
public static Collector<Pair<CharacterDTO, MovieCharacter>, Map<CharacterDTO, MovieCharacter>, Map<CharacterDTO, MovieCharacter>> getCharacterMapper() {
return new NullTolerantMapCollector<>();
}
@Override
public Supplier<Map<T, E>> supplier() {
return HashMap::new;
}
@Override
public BiConsumer<Map<T, E>, Pair<T, E>> accumulator() {
return NullTolerantMapCollector::put;
}
private static <T,E> void put(Map<T, E> map, Pair<T, E> pair) {
map.put(pair.key, pair.value);
}
@Override
public BinaryOperator<Map<T, E>> combiner() {
return NullTolerantMapCollector::combine;
}
private static <T, E> Map<T, E> combine(Map<T, E> map1, Map<T, E> map2) {
map1.putAll(map2);
return map1;
}
@Override
public Function<Map<T, E>, Map<T, E>> finisher() {
return Function.identity();
}
@Override
public Set<Characteristics> characteristics() {
return Collections.singleton(Characteristics.IDENTITY_FINISH);
}
}
package edu.hsh.dbs2.imdb.util; package edu.hsh.dbs2.imdb.util;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
public class Util { public class Util {
private Util() {} private Util() {}
public static <T> boolean isNullOrEmpty(Collection<T> coll) {
return coll == null || coll.isEmpty();
}
public static Map<String, String> getTestDataProperty() {
var properties = new HashMap<String, String>();
properties.put("jakarta.persistence.sql-load-script-source", "src/main/resources/TestData.sql");
return properties;
}
} }
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence xmlns="https://jakarta.ee/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0" <persistence xmlns="https://jakarta.ee/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0"
xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"> xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd">
<persistence-unit name="edu.hsh.dbs2.imdb"> <persistence-unit name="edu.hsh.dbs2.imdb" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties> <properties>
<property name="jakarta.persistence.jdbc.driver" value="oracle.jdbc.driver.OracleDriver"/> <property name="jakarta.persistence.jdbc.driver" value="oracle.jdbc.driver.OracleDriver"/>
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
<property name="jakarta.persistence.schema-generation.create-script-source" value="src/main/resources/Schema.sql"/> <property name="jakarta.persistence.schema-generation.create-script-source" value="src/main/resources/Schema.sql"/>
<property name="jakarta.persistence.schema-generation.drop-script-source" value="src/main/resources/DropSchema.sql"/> <property name="jakarta.persistence.schema-generation.drop-script-source" value="src/main/resources/DropSchema.sql"/>
<property name="hibernate.check_nullability" value="true"/> <property name="hibernate.check_nullability" value="true"/>
<property name="hibernate.jdbc.use_getGeneratedKeys" value="true"/> <property name="hibernate.hbm2ddl.auto" value="validate"/>
</properties> </properties>
</persistence-unit> </persistence-unit>
</persistence> </persistence>
\ No newline at end of file
package edu.hsh.dbs2.imdb; package edu.hsh.dbs2.imdb;
import edu.hsh.dbs2.imdb.entity.*; import edu.hsh.dbs2.imdb.entity.*;
import edu.hsh.dbs2.imdb.util.Util;
import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence; import jakarta.persistence.Persistence;
import jakarta.persistence.PersistenceException; import jakarta.persistence.PersistenceException;
...@@ -19,9 +20,7 @@ public class TestDB { ...@@ -19,9 +20,7 @@ public class TestDB {
@BeforeClass @BeforeClass
public static void setUp() { public static void setUp() {
var properties = new HashMap<String, String>(); sessionFactory = Persistence.createEntityManagerFactory("edu.hsh.dbs2.imdb", Util.getTestDataProperty());
properties.put("jakarta.persistence.sql-load-script-source", "src/main/resources/TestData.sql");
sessionFactory = Persistence.createEntityManagerFactory("edu.hsh.dbs2.imdb", properties);
} }
@AfterClass @AfterClass
...@@ -73,4 +72,28 @@ public class TestDB { ...@@ -73,4 +72,28 @@ public class TestDB {
assertEquals("Bob", character.get().getActor().getName()); assertEquals("Bob", character.get().getActor().getName());
assertEquals(Sex.m, character.get().getActor().getSex()); assertEquals(Sex.m, character.get().getActor().getSex());
} }
@Test
public void testInsertDeleteMovie() {
@Cleanup var em = sessionFactory.createEntityManager();
var movie = new Movie();
movie.setTitle("The Matrix");
movie.setType(MovieType.C);
movie.setYear(1998);
em.getTransaction().begin();
em.persist(movie);
em.flush();
em.getTransaction().commit();
var cb = em.getCriteriaBuilder();
var cq = cb.createQuery(Movie.class);
var root = cq.from(Movie.class);
cq.select(root).where(cb.equal(root.get("id"), movie.getId()));
var sameMovie = em.createQuery(cq).getSingleResult();
assertEquals(movie.getTitle(), sameMovie.getTitle());
assertEquals(movie.getType(), sameMovie.getType());
assertEquals(movie.getYear(), sameMovie.getYear());
em.getTransaction().begin();
em.remove(sameMovie);
em.getTransaction().commit();
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment