회사의 배당금 조회를 해주는 프로젝트 강의를 클론 코딩을 할 때 분명 똑같이 쳤는데 오류가 발생해 당황스러웠다.

처음 만난 오류는 이것이었다.

org.hibernate.MappingException: Could not determine type for: java.util.List, at table: member, for columns: [org.hibernate.mapping.Column(roles)]

회원 엔티티 안에 권한 정보를 가지는 roles 컬럼에서 타입을 정할 수 없다는 내용이었다.

private List<String> roles;

-> 변경
@ElementCollection(targetClass = String.class)
private List<String> roles;

검색 끝에 @ElementCollection(targetClass = String.class) 어노테이션을 붙이면 되겠다는 결론을 얻고 시도해봤더니 프로그램이 실행되어 이제 됐다!! 했었는데 두번째 오류가 또 발생했다.

배당금 정보를 가져올 회사를 조회하고 회사와 배당금 정보를 저장하는 과정에서 '쓰기 권한'을 갖는 사람만이 그것을 할 수 있도록 설정되어있었는데, postman으로 쓰기 권한을 가진 회원을 만들고 로그인해서 회사를 저장하는 api를 실행하는 과정에서 이 오류가 발생한 것이다.

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role

이 오류는 영속성 컨텍스트 문제였다. JPA에서 지연로딩을 하려면 항상 영속성 컨텍스트가 있어야 하지만 영속성 컨텍스트가 종료되어 버려서, 지연 로딩을 할 수 없어서 발생하는 오류라고 한다.

구글 검색으로 이것저것 보면서 @Transactional 어노테이션도 붙여보고 @OneToMany(mappedBy = "member", fetch = FetchType.EAGER) 어노테이션도 붙어보고 별짓 다했는데 해결하지 못했다.

@Transactional은 어디 붙이는지 몰라서 서비스 이곳 저곳에 다 붙여보면서 시도해봐도 소용이 없었고,
@OneToMany(mappedBy = "member", fetch = FetchType.EAGER)도 roles 컬럼 위에 붙여봤다가 또 다른 오류를 만났다.

org.hibernate.AnnotationException: Use of @OneToMany or @ManyToMany targeting an unmapped class: com.dayone.persist.entity.MemberEntity.roles[java.lang.String]

지연로딩을 하지 않고 즉시 로딩을 위해 LAZY를 EAGER로 바꾸려고 @OneToMany를 쓴 것이었는데 저거때문에 또 오류가 생기는 것이었다.

그러다 번뜩 든 생각이 @ElementCollection 여기에 fetch를 추가할 수 없는가? 하는 생각이 들어서 써봤는데 자동완성이 뜨는 것이다..!

@ElementCollection(targetClass = String.class, fetch = FetchType.EAGER)
private List<String> roles;

유레카!! 드디어 해결되었다!! 애플리케이션을 실행시키고 postman을 통해 쓰기 권한을 가진 회원을 만들어 로그인하고 회사를 추가해봤더니 드디어 추가가 된다!!! 진짜 이것때문에 며칠을 검색하고 고민했는데 묵은 체증이 싹 가시는 기분이다.
너무 후련하다~~!!

0개의 댓글