이 내 PersistenceUtil 클래스 ..병합은 어떻게 LazyInitException을 피할 수 있습니까?
package biz.tugay.learningjpa.persistence;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public class PersistenceUtilImpl implements PersistenceUtil {
private EntityManagerFactory entityManagerFactory;
public PersistenceUtilImpl(final String persistenceUnit) {
entityManagerFactory = Persistence.createEntityManagerFactory(persistenceUnit);
}
public EntityManager getEntityManager() {
final EntityManager entityManager = entityManagerFactory.createEntityManager();
return entityManager;
}
public void closeFactory() {
entityManagerFactory.close();
}
}
그리고이 내 엔티티입니다 ..
Actor.java
package biz.tugay.learningjpa.model;
import javax.persistence.*;
import java.util.List;
@Entity
public class Actor {
private Integer id;
private String firstname;
private String lastname;
private List<Film> films;
@Id
@Column(name = "actor_id")
@GeneratedValue(strategy = GenerationType.AUTO)
public Integer getId() {
return id;
}
public void setId(Integer actor_id) {
this.id = actor_id;
}
@Basic
@Column(name = "first_name")
public String getFirstname() {
return firstname;
}
public void setFirstname(String first_name) {
this.firstname = first_name;
}
@Basic
@Column(name = "last_name")
public String getLastname() {
return lastname;
}
public void setLastname(String last_name) {
this.lastname = last_name;
}
@ManyToMany
@JoinTable(name = "film_actor",
joinColumns = @JoinColumn(name = "actor_id"),
inverseJoinColumns = @JoinColumn(name = "film_id")
)
public List<Film> getFilms() {
return films;
}
public void setFilms(List<Film> films) {
this.films = films;
}
}
및 Film.java
package biz.tugay.learningjpa.model;
import javax.persistence.*;
import java.util.List;
@Entity
public class Film {
private Integer id;
private String title;
private List<Actor> actors;
@Id
@Column(name = "film_id")
@GeneratedValue(strategy = GenerationType.AUTO)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Basic
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
@ManyToMany
@JoinTable(name = "film_actor",
joinColumns = @JoinColumn(name = "film_id"),
inverseJoinColumns = @JoinColumn(name = "actor_id"))
public List<Actor> getActors() {
return actors;
}
public void setActors(List<Actor> actors) {
this.actors = actors;
}
}
입니다
그리고 나는 내 모델 2 개 서비스가 있습니다
ActorServiceImpl.java 아래와 같이 나는이 검사를
public final class ActorServiceImpl implements ActorService {
private final PersistenceUtil persistenceUtil;
public ActorServiceImpl(PersistenceUtil persistenceUtil) {
this.persistenceUtil = persistenceUtil;
}
@Override
public List<Actor> getActorsOfFilm(Film film) {
final EntityManager entityManager = persistenceUtil.getEntityManager();
final Film mergedFilm = entityManager.merge(film);
final ArrayList<Actor> actors = new ArrayList<Actor>();
actors.addAll(mergedFilm.getActors());
entityManager.close();
return actors;
}
}
및 FilmServiceImpl.java
public final class FilmServiceImpl implements FilmService {
private final PersistenceUtil persistenceUtil;
public FilmServiceImpl(final PersistenceUtil persistenceUtil) {
this.persistenceUtil = persistenceUtil;
}
@Override
public Film filmById(int filmId) {
final EntityManager entityManager = persistenceUtil.getEntityManager();
final Film film = entityManager.find(Film.class, filmId);
entityManager.close();
return film;
}
}
:
를public class ActorServiceImplTest {
private PersistenceUtilImpl persistenceUtil;
private ActorServiceImpl actorService;
@Before
public void init() {
persistenceUtil = new PersistenceUtilImpl("sakiladb");
actorService = new ActorServiceImpl(persistenceUtil);
}
@After
public void tearDown() {
persistenceUtil.closeFactory();
}
@Test(expected = LazyInitializationException.class)
public void testGetActorsOfFilmLazyInit() {
final FilmServiceImpl filmService = new FilmServiceImpl(persistenceUtil);
final Film film = filmService.filmById(1);
for (Actor actor : film.getActors()) {
System.out.println(actor.getFirstname());
}
}
@Test
public void testGetActorsOfFilm() {
final FilmServiceImpl filmService = new FilmServiceImpl(persistenceUtil);
final Film film = filmService.filmById(1);
final List<Actor> actorsOfFilm = actorService.getActorsOfFilm(film);
for (Actor actor : actorsOfFilm) {
System.out.println(actor.getFirstname());
}
}
}
그래서 첫 번째 테스트에서는 LazyInitException이 발생합니다. EntityManager는 영화 배우를 얻는 시점까지 닫힙니다.
두 번째 테스트에 대해서는 "testGetActorsOfFilm"이라고합니다. 이 메시지는 데이터베이스에서 콘솔의 액터를 전달하고 인쇄합니다.이 작업은 entityManager.merge (film); 내가 이해하는 한. 우리는 분리 된 필름 객체를 전달하고 그것을 PersistenceContext에 병합 한 다음 구현에서 영화의 액터를 얻습니다.
는하지만, 무엇 내가 물어보고 싶은, 왜이 시험은 실패 않습니다
@Test
public void testGetActorsOfFilm() {
final Film film = new Film();
film.setId(1);
final List<Actor> actorsOfFilm = actorService.getActorsOfFilm(film);
for (Actor actor : actorsOfFilm) {
System.out.println(actor.getFirstname());
}
}
나의 이해는, 나는 ID가 1 인 경우 필름 객체를 생성하고 서비스 방식으로 전달하고있다. 따라서 entityManager.merge (film)는 Database에서 필름을로드하고 Persistence Context와 동기화해야합니까? 그러나 내가보고하고 모든입니다
그래서 내가 혼란 스러워요java.lang.NullPointerException
at java.util.ArrayList.addAll(ArrayList.java:559)
at biz.tugay.learningjpa.service.ActorServiceImpl.getActorsOfFilm(ActorServiceImpl.java:57)
, 첫번째 상황에서 내가 가지고있는 분리 된 개체와 두 번째 상황의 차이는 무엇인가? 이드와 일만 병합하지 않습니까?
Null 포인터 예외를 피하는 적절한 방법은 getActorsOfFilm에서 EntityManager.find를 사용하는 것입니다. –
예, 내 대답에 설명되어 있습니다. –
어쨌든 actors.addAll (mergedFilm.getActors());를 피할 수 있습니까? 왜냐하면 내가 새로운 Collection에 필름을 추가하지 않는다면, 나는 여전히 LazyInitException을 얻을 것이다 .. –