TIL, WIL

[TIL] S3이미지 업로드 시 게시글이 두번 작성되는 문제

KJihun 2023. 8. 3. 18:02
728x90

프로젝트 진행 간 우리 조는 물물교환 사이트를 만들기로 했다.

게시글 등록 시 이미지를 등록할 수 있기에 S3에 이미지를 업로드 후 Repository에 등록을 하던 중에 발생한 문제였다.

분명 게시글 작성을 한번만 했는데 두개가 등록이 됐으며 

하나는 이미지를 제외한 모든 값이 null이었고, 하나는 모든 값을 포함하지만 image를 가지지 못하였다.

 

(Goods와 Image는 ManyToOne관계이다.)

 

ServiceCode

@Transactional
    public ApiResponse<GoodsResponseDto> goodsCreate(GoodsRequestDto requestDto, List<MultipartFile> images) {
        List<String> imageUuids = imageHelper.saveImagesToS3AndRepository(images, amazonS3, bucket, goods);
        Goods goods = new Goods(requestDto);
        goodsRepository.save(goods);

        return new ApiResponse<>(true, new GoodsResponseDto(goods, imageUuids), null);
    }

 

saveImagesToS3AndRepositoryCode

public List<String> saveImagesToS3AndRepository(List<MultipartFile> images, AmazonS3 amazonS3, String bucket, Goods goods) {

			...

            // S3 버킷에 등록
            amazonS3.putObject(request);
            uploadedFileUuids.add(imageUuid);

	// ImageRepository에 등록
            imageRepository.save(new Image(imageUuid, amazonS3.getUrl(bucket, imageUuid).toString(), goods));
        }

        return uploadedFileUuids;
    }

 

왜 이런 상황이 발생한걸까 곰곰히 생각하고 디버깅을 하며 하나하나 찾아봤다. 문제는 

 List<String> imageUuids = imageHelper.saveImagesToS3AndRepository(images, amazonS3, bucket, goods);

코드 이후에 goodsRepository.save(goods); 를 작성했기 때문이었다.

 

saveImagesToS3AndRepository 메서드 내부에서 goods를 활용하여 Image 엔티티를 생성하는데,

goods가 영속성 컨텍스트에 저장되기 전에 `imageRepository.save(new Image(imageUuid, amazonS3.getUrl(bucket, imageUuid).toString(), goods));에서 goods 를 사용하여 저장한다.

영속성 컨텍스트에 저장되지 않아 null값인  goods를 사용해 이미지를 저장 후

ServiceCode에서 save를 통해 영속성 컨텍스트에 goods가 저장되었기에 발생한 사고였다.

해결한 코드

@Transactional
    public ApiResponse<GoodsResponseDto> goodsCreate(GoodsRequestDto requestDto, List<MultipartFile> images) {
        Goods goods = new Goods(requestDto);
        goodsRepository.save(goods);
        List<String> imageUuids = imageHelper.saveImagesToS3AndRepository(images, amazonS3, bucket, goods);

        return new ApiResponse<>(true, new GoodsResponseDto(goods, imageUuids), null);
    }

임시방편으로 save를 먼저 하도록 하여 영속성 컨텍스트에 저장한 이후 S3에 저장하게 했다.

프로젝트가 끝나기 전까지 더 좋은 방법을 찾아보고 해결할 수 있도록 해야겠다.

 

'TIL, WIL' 카테고리의 다른 글

[WIL] week 9  (0) 2023.08.14
[WIL] week 8  (1) 2023.08.06
[TIL] SQLsyntaxerrorexception  (0) 2023.08.02
[WIL] week 7  (0) 2023.07.30
[WIL] week 6  (1) 2023.07.23