2022. 7. 22. 17:21ㆍJAVA
초보자 삽질 귀여움주의;; 도움 안됨주의;;
프로젝트 진행 중, DB에서 단건조회를 하고 Optional로 감싸져서 반환되는 값을 처리하고 있었다..
게시글 추천 기능을 구현하려고 user_id 속성과 post_id 속성이 복합적으로 유니크하게 존재해야 했는데, 테이블 상에서 묶어서 unique로 관리하는 것은 뭔가 맘에 들지 않았다. 그래서 id속성을 따로 만들고 개발자가 수작업으로 데이터 정합성을 관리하려고 했다.
추천_테이블 코드:
@Repository
public interface PostRecommendRepository extends JpaRepository<PostRecommend, Long> {
@Query("select pr from PostRecommend pr where pr.user.userId=:userId and pr.post.postId=:postId")
Optional<PostRecommend> findByUsersIdAndPostId(@Param("postId") Long postId,@Param("userId") Long userId);
}
서비스레이어 코드:
@Transactional
public void postRecommendCount(PostRecommendRequest postRecommendRequest) {
Post post = postRepository.findById(postRecommendRequest.getPostId()).
orElseThrow(() -> new IllegalArgumentException("해당하는 postId가 없습니다. 잘못된 입력"));
Users user = userRepository.findById(postRecommendRequest.getUserId())
.orElseThrow(() -> new IllegalArgumentException("해당하는 userId가 없습니다"));
postRecommendRepository.findByUsersIdAndPostId(post.getPostId(), user.getUserId())
.ifPresent(i -> new IllegalStateException("해당 유저가 이미 추천한 게시물입니다."));
PostRecommend postRecommend = PostRecommend.builder()
.post(post)
.user(user)
.createdAt(LocalDateTime.now())
.build();
postRecommendRepository.save(postRecommend);
}
중간 쯤에 있는 ifPresent() 메서드를 활용해서, 이미 user_id와 post_id를 복합적으로 갖고있는 레코드가 존재하면 IllegalStateException()을 터트리려는 것이 주요한 로직이었다.
근데, 포스트맨으로 아무리 중복 요청을 보내도 에러가 안터진다................. 그냥 DB에 계속 데이터만 쌓인다
ifPresent()를 잘 사용한 것인지 글도 계속 찾아보고 예제도 찾아봤는데 참 이상허다...
그냥 복합 unique 제약조건을 걸까 하던 참에.. 스택오버플로우의 글을 하나 보게 되었다
https://stackoverflow.com/questions/28596790/throw-an-exception-if-an-optional-is-present
ifPresent()는 consumer 라는 함수형 인터페이스를 인자를 받는다. 입력은 있고 출력은 없는 형태라고 생각하면 된다.
그래서 람다식의 왼쪽 부분이 필수적인 것은 인텔리제이에서 알려줘서 인지하고 있었다.
오른쪽 부분은 consumer의 반환타입이 void 이므로.. i를 써도 되고 안써도 된다. 반환값이 void기만 하면 된다. 그래서 오류를 던진 것이었는데...
postRecommendRepository.findByUsersIdAndPostId(post.getPostId(), user.getUserId())
.ifPresent(i -> new IllegalStateException("해당 유저가 이미 추천한 게시물입니다."));
postRecommendRepository.findByUsersIdAndPostId(post.getPostId(), user.getUserId())
.ifPresent(i -> {throw new IllegalStateException("해당 유저가 이미 추천한 게시물입니다.");});
알고보니 new로 exception을 생성만 되고 그냥 버려지고 있었다.
ㅎㅎ; 중괄호로 감싸고 throw 를 넣어주니 잘 작동한다. (허무)
삽질은 조금 했지만 함수형 인터페이스에 대해서 조금 더 알게 되었다.
근데 중괄호는 왜 필요한거지..
'JAVA' 카테고리의 다른 글
[Spring + Redis] 오류 org.springframework.data.redis.serializer.SerializationException: Cannot deserialize; (0) | 2022.07.29 |
---|---|
[Spring + Redis] 레디스로 게시글 조회수 중복 카운팅 검증하기 (1) | 2022.07.27 |
인스턴스화를 막기 위한 private 생성자 (2) | 2022.05.18 |
[Spring + DB] 트랜잭션과 스프링 (0) | 2022.05.13 |
[SPRING] 인프런 스프링 기본편 강의 공부기록. 下 (완) (0) | 2022.03.07 |