티스토리 뷰
JPA 사용 시 DB에서 조회된 엔터티를 view 단에서 사용해야 할 경우가 많이 생깁니다. 보통 jackson을 이용하여 json으로 parsing 후 사용하게 되는데, 엔터티간의 관계가 복잡할 경우 문제가 생길 수 있습니다. 예를들어 순환관계(A > B > C > A)나 양방향 관계(A <-> B)를 가질 경우 자칫 잘못하면 json parsing 시 무한루프에 빠지게 됩니다. (이클립스가 뻗어 버리더군요...) 이를 방지하기 위한 방법으로 몇 가지가 있지만, 제가 사용한 방법은 다음과 같습니다.
1. OSIV disable
OSVI는 transaction 밖에서도 lazy loading을 사용할 수 있도록 해주는 기능입니다. 이 기능을 사용하면 개발 시 편리한 점이 있지만, 자신의 컨트롤 밖의 문제가 생길 수 있기 때문에 좀 더 명확한 개발을 위해서는 사용하지 않는게 좋습니다.
Spring boot 사용 시에는 기본적으로 사용하도록 설정되어 있습니다. 사용하지 않도록 설정을 변경합니다.
jap.open-in-view : false
2. mapper의 module 설정
이제 view 단에서 lazy loading을 사용할 수 없습니다. 엔터티간의 순환관계가 있더라도 계속 연결고리를 타고 들어가는 일은 없는거죠. transaction 안에서 조회된 값만 view 단에서 사용할 수 있습니다. 하지만, 이 상태에서 발생되는 문제는 lazy loading을 위한 proxy 객체 조회 시 오류가 발생한다는 것 입니다. (org.hibernate.LazyInitializationException: could not initialize proxy 오류 발생)
이럴 경우 proxy 객체를 null로 변환시켜주는 장치가 필요합니다.
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new Hibernate5Module());
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
jsonConverter.setObjectMapper(objectMapper);
return jsonConverter;
}
3. 이제 view단에서 사용할 엔터티만 명시적으로 fetch join으로 조회하면 됩니다.
'개발 > Java' 카테고리의 다른 글
Devtools object casting fail (0) | 2017.04.03 |
---|---|
Restful API 개발 참고 사항 요약 (0) | 2016.11.08 |
Java Method Overriding (0) | 2016.06.17 |
String #2 객체 비교 (0) | 2016.06.03 |
Java String #1 (0) | 2016.05.30 |