해결된 질문
작성
·
195
1
안녕하세요 또 질문드리게 되었네요^^
항상 감사드립니다
1. EntityManager Thread Safe 질문
책을 보던 중 책 91페이지에
- EntityManager는 스레드 간에 절대 공유하면 안된다고 되어 있습니다
강의 중 예제에서 Repository 생성하실 때 Spring Data Jpa에서 제공하는 JpaRepository 사용하지 않고 직접 EntityManager 주입받아서 사용하시던데 이 때 Spring 기본 정책인 싱글턴 빈이 등록되면 모든 쓰레드가 하나의 EntityManager를 공유하는 것이 아닌지에 대한 의문이 들어 질문드립니다
2. Spring OSIV 사용 시 Controller에서 Lazy 로딩 후 Object -> JSON 변환 중 serialize 방법
- REST API서버를 개발중입니다
Controller에서 Lazy 로딩 후 jackson의 API를 이용해서 Object -> JSON 변환하는 중 프록시 객체의 "hibernateLazyInitializer", "handler" 2개의 필드가 getter가 없어 serialize 실패하는 현상이 있습니다
현재까지 생각한 해결 방법은 아래의 2가지 방법입니다
1) Mapper 변환 옵션에서 2개의 필드만 except 처리
2) Mapper 사용하지 않고 2개의 필드를 제외한 각 필드의 Getter를 호출해서 직접 Json String 생성
Controller에서 Lazy 로딩을 하는 상황에서 위 2가지 방법이 아닌 다른 방법이 있는지 궁금합니다
답변 2
1
1
안녕하세요 jhwoo님^^
1. 책 13.1 트랜잭션 범위의 영속성 컨텍스트(578p)를 보시면 원하는 답을 얻으실 수 있을 거에요^^
스프링 컨테이너가 주입하는 EntityManager는 사실 진짜 EntityManager가 아니라 가짜 객체입니다. 이 가짜 객체가 현재 트랜잭션에 물려있는 영속성 컨텍스트(진짜 EntityManager)를 찾아서 연결해 줍니다.
2. 이 부분은 hibernate5module로 검색해보시면 원하는 답을 구할 수 있을 꺼에요. 결국 지연 로딩이 되면 객체가 진짜 객체가 아니라 프록시 객체인데, Jackson JSON 라이브러리가 이것을 모르고, 파싱할 수 없기 때문에 발생하는 문제입니다. 그래서 Jackson JSON이 하이버네이트 프록시 객체를 인지할 수 있게 라이브러리를 등록해주어야 합니다.
그런데! 이렇게 엔티티를 직접 API로 노출하는 것은 유지보수 관점에서 좋은 방법이 아닙니다. 결국 DTO로 변환해서 처리해야 합니다.
2번처럼 API 하나를 개발해도 JPA를 사용하면, 엔티티라는 개념이 들어가면서 고민할 거리가 많아집니다. 엔티티를 API에 직접 노출해야 하나? 아니면 별도의 객체를 별도로 만들어서 반환해야 하나? 엔티티를 반환하면 지연 로딩은 어떻게 처리해야 하나? 등등 수 많은 고민을 하게 됩니다. 내일 오픈 예정인 활용편 2탄에서 실무에서 어떻게 구현하는 것이 안전하고, 유지보수하기 좋은 방법인지 실전 노하우를 알려드립니다^^! (이건 광고요 ㅎㅎ)
감사합니다.