com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: ~어쩌고
게시글을 find해오는 과정에서 이 에러가 뜬다.
게시글 엔티티에서는 @ManyToOne(fetch=FetchType.LAZY)으로 User 객체를 가지고 있는데, 컨트롤러로 반환할 때 db에서 dto로 잘 꺼내오는데 이 dto 객체를 ResponseBody를 통해 json으로 컨트롤러에 반환하는데서 문제가 생긴것이다.(값은 있는 것임)
fetch를 EAGER로 가져오면(LAZY로 설정하지 않고 ManyToOne 기본 설정) 문제없이 잘 발생한다.
--> 하지만 현업에서는 ManyToOne을 LAZY로 설정해야하기 때문에 EAGER일 때는 배제한다.
--> Board에 관한 정보만 받아오고 싶은데 user의 정보까지 모두 다 받아오는 것을 방지하기 위해서 jpa에서 지연로딩과 프록시를 지원한다!!
➡︎💡 왜 LAZY로 못받아올까?
현재 프로젝트에 jwt, spring security가 설정돼있는 상태인데, board dto에서 user의 정보를 넣어줄 때 pwd가 없다고 에러가 뜬다?
-> security 설정에서 뭔가 user는 pwd(비밀번호) 컬럼의 값이 있어야하고,(user는 프록시객체로 불러왔기 때문에 직접적으로 user객체의 값을 호출하기 전까지는 user는 가짜객체로 존재한다. 이는 성능 낭비를 위함, 프록시 객체로 해결할 수 없는 경우(값을 조회)에는 db에 데이터를 가져오기 위해 쿼리를 한번 더 날린다 => N+1문제 발생 => fetch join으로 해결해야함) lazy에서는 @Transactional이 끝난 후에 select해서 관련된 user의 정보를 가져오는 것이고 eager는 @Transactional 내에서 user의 정보를 select해오기 때문에 에러가 뜨는 것 같다..
결론
find 메서드 위에 join fetch나 EntityGraph를 사용해서 Lazy여도 한번에 user객체를 가져오도록 한다.
개념을 잡기에 좋은 글

-> User는 프록시객체이기 때문에
fetch join, Entity Graph
- fetch join은 inner join을 사용하고, EntityGraph은 left outer join을 사용한다. 우리는 페이징을 사용해야하기 때문에 fetch join은 사용하지 못하고 EntityGraph을 사용하려 했다.
하지만 inner join이 더 효율성이 좋은 것 같은데, 이문제는 어떻게 해야하지? 라는 물음이 있었다.
답변 : inner join이 퍼포먼스 상으로 좋은 것은 맞다. 하지만 jpa에서 제공해주는 paging기능을 사용하려면 left outer join을 사용해야한다.
하지만 이런 이유로 left outer join을 사용하는 것은 좋지 않을 수 있다. 그래서 이때 PageBean 클래스를 만들어서 페이징을 따로 처리해주는 것이다.
→ 여기서 딜레마가 생긴다. 회사마다 서비스마다 선택해서 사용하면 될 것 같다고 말씀해주셨다.
→ 이건 보통 n+1과 관련해서 사용하는데, 그 경우 아니더라도 사용해도된다~
fetch join과 EAGER의 차이점?
꼭 읽어야하는 블로그