ORM/JPA

[Error] org.hibernate.LazyInitializationException: could not initialize proxy

잔망루피 2022. 7. 20. 21:58
반응형
org.hibernate.LazyInitializationException: could not initialize proxy [Bulletin.Board.domain.posts.User#38] - no Session

org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint ["FK8KCUM44FVPUPYW6F5BACCX25C: PUBLIC.COMMENT FOREIGN KEY(USER_ID) REFERENCES PUBLIC.USER(ID) (71)"; SQL statement:
delete from user where id=? [23503-200]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement

Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement

Caused by: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Referential integrity constraint violation: "FK8KCUM44FVPUPYW6F5BACCX25C: PUBLIC.COMMENT FOREIGN KEY(USER_ID) REFERENCES PUBLIC.USER(ID) (71)"; SQL statement:
delete from user where id=? [23503-200]
@Test
public void commentSave(){
    // given
    String name="hello00";
    Long id=postRepository.findAll(Sort.by("id")).get(0).getId();
    String content="반가워요";

    // when
    Long comment_id=commentService.commentSave(name, id, content);
    Comment comment=commentService.findById(comment_id);

    // then
    assertThat(comment.getUser().getUsername()).isEqualTo("hello00");
    assertThat(comment.getComment()).isEqualTo("반가워요");
    assertThat(comment.getPost().getId()).isEqualTo(id);
}

COMMENT 테이블과 USER 테이블은 M:1로 매핑되어있다.

지연 로딩을 사용했다.

User user=comment.getUser();

user에 프록시 객체를 넣어둔다.

데이터가 필요할 때가 되어야 데이터베이스를 조회해서 프록시 객체를 초기화

트랜잭션의 범위는 Service와 Repository다.

Comment comment=commentService.findById(comment_id);

findById 메소드 호출 후 영속성 컨텍스트가 이미 끝났다.

트랜잭션이 끝나면 영속성 컨텍스트도 종료된다.

스프링 컨테이너는 트랜잭션 범위의 영속성 컨텍스트 전략을 기본으로 사용하기 때문이다.

 

assertThat(comment.getUser().getUsername()).isEqualTo("hello00");

준영속 상태는 영속성 컨텍스트가 없어서 지연 로딩을 시도하면 문제가 발생한다.

 

 

✨ 해결

@Test
@Transactional
public void commentSave(){
    // given
    String name="alswjd00";
    Long id=postRepository.findAll(Sort.by("id")).get(0).getId();
    String content="반가워요";

    // when
    Long comment_id=commentService.commentSave(name, id, content);
    Comment comment=commentService.findById(comment_id);

    // then
    assertThat(comment.getUser().getUsername()).isEqualTo("alswjd00");
    assertThat(comment.getComment()).isEqualTo("반가워요");
    assertThat(comment.getPost().getId()).isEqualTo(id);
}

테스트 메서드에 @Transactional붙여서 해결

트랜잭션이 같으면 같은 영속성 컨텍스트를 사용한다.

 

 

 

참고 👇

자바 ORM 표준 JPA 프로그래밍

 

https://yeon-kr.tistory.com/190

 

JPA 지연 로딩, 결국 Proxy

1) 서론 JPA가 적용된 서버의 로그를 보면, LazyInitializationException이 빠지지 않고 항상 올라오곤 합니다. 일주일에 한 개씩은 발생하는 에러 같은데요. 사실 이는 단순한 문법적 오류이며, 하이버네

yeon-kr.tistory.com

 

https://programmer-chocho.tistory.com/81

 

JPA에서 지연로딩(LAZY LOADING)이란

JPA 공부를 하다가 아래와 같은 오류를 만났다. org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.study.chapter05.entity.Ch05Team.memberList, could not in..

programmer-chocho.tistory.com

 

반응형

'ORM > JPA' 카테고리의 다른 글

[JPA] OneToOne  (1) 2024.03.17
N+1 문제  (0) 2022.10.27
@JoinColumn  (0) 2022.05.19
변경 감지(Dirty Checking)  (0) 2022.05.18
JPA를 이용한 데이터베이스 초기화  (0) 2022.03.31