1 분 소요

문제 상황

Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: fittering.mall.domain.entity.Mall.favorites: could not initialize proxy - no Session

프로젝트에서 MapStruct를 통해 DTO와 일부 파라미터를 함께 조합해서 Product 엔티티 객체를 생성하는 로직에서 예외가 발생
했다. Product 내에 favorites 필드가 Favorite과 연관관계를 맺고 있어서 이를 초기화해주는 로직을 MapStruct에서
만들어줬고, 애플리케이션 실행 후 해당 로직을 테스트하는 과정에서 문제가 발생했다.

//MapStruct Mapper에 정의된 함수
public Product toProduct(CrawledProductDto crawledProductDto, String image, Integer view, Integer timeView, Category category, SubCategory subCategory, Mall mall) {
if ( crawledProductDto == null && image == null && view == null && timeView == null && category == null && subCategory == null && mall == null ) {
    return null;
}

//ProductMapperImpl에 정의된 롲기
Product.ProductBuilder product = Product.builder();

if ( crawledProductDto != null ) {
    product.name( crawledProductDto.getName() );
    product.origin( crawledProductDto.getUrl() );
    product.price( crawledProductDto.getPrice() );
    product.gender( crawledProductDto.getGender() );
    product.type( crawledProductDto.getType() );
    product.disabled( crawledProductDto.getDisabled() );
}
if ( mall != null ) {
    product.mall( mallToMall( mall ) );
    product.image( mall.getImage() );
    List<Favorite> list = mall.getFavorites(); //favorites를 초기화 해주고 있음
    if ( list != null ) {
        product.favorites( new ArrayList<Favorite>( list ) );
    }
}

//Product 엔티티 정보
public class Product {

    @Id @GeneratedValue
    @Column(name = "product_id")
    private Long id;

    @NonNull @Length(max = 50)
    private String name;

    @OneToMany(mappedBy = "product")
    private List<Favorite> favorites = new ArrayList<>();
    ...
}

해결

Product에서 Favorite을 지연 로딩때문에 프록시로 들고왔는데 초기화 로직을 수행해야해서 트랜잭션이 필요했다.
하지만 해당 로직이 포함된 함수에서는 DB 데이터를 수정하는 작업이 있으므로 @Transactional을 설정해주니 해결할 수 있었다.

@Transactional //추가
public void updateCrawledProducts(...) {
  Product product = save(ProductMapper.INSTANCE.toProduct(
                productDto, thumbnail, 0, 0, category, subCategory, mall));
  ...
}

카테고리:

업데이트:

댓글남기기