본문 바로가기

실시간 채팅 솔루션 개발/문제 해결 사례

(5)
Entity 삭제 시 발생하는 Referential integrity constraint violation 에러 엔티티를 삭제하는 기능을 개발하는 과정에서 Referential integrity constraint violation 에러가 발생하며 삭제되지 않는 상황이 생겼고, 이를 해결한 방법을 이야기해보려 합니다. 실제로 발생한 에러 메시지는 아래와 같습니다."could not execute statement [Referential integrity constraint violation: \"FKLLBJ31M7Y971AVM7XQG615NIY: PUBLIC.USER_CHAT_ROOM FOREIGN KEY(CHATROOM_ID) REFERENCES PUBLIC.CHAT_ROOM(CHATROOM_ID) (CAST(5 AS BIGINT))\"; SQL statement:\ndelete from chat_room whe..
그럼 모든 JPA 에러는 롤백 처리해야 할까? (트랜잭션 롤백 여부) https://praaay.tistory.com/31 JPA가 던지는 check-error를 uncheck-error로 변환하면, 트랜잭션이 rollback 될까?Respository 계층 메소드들을 예외 처리하며 JPA가 던지는 에러를 어떻게 처리해야 할지 고민이었습니다.JPA가 던지는 에러는 아래와 같이 트랜잭션을 기본적으로 롤백하는 언체크 에러도 있고, 트praaay.tistory.com위 글에 이어서 제 궁금증은 JPA가 던지는 모든 에러를 언체크 에러로 변환하여 트랜잭션 롤백하면 되지 않을까? 생각했었습니다. 어떤 처리를 하는 과정에서 문제가 발생하면 그 처리의 흔적이 데이터베이스나 캐시등에 남아있으면 안 되지 않을까라는 생각이 있었기 때문입니다. 하지만 JPA 표준에서는 '트랜잭션 롤백을 표시..
JPA가 던지는 체크 에러를 언체크 에러로 변환하면, 트랜잭션이 롤백 될까? Respository 계층 메소드들을 예외 처리하며 JPA가 던지는 에러를 어떻게 처리해야 할지 고민이었습니다. JPA가 던지는 에러는 아래와 같이 트랜잭션을 기본적으로 롤백하는 언체크 에러도 있고, 트랜잭션을 롤백하지 않는 체크 에러도 있습니다. 물론 JPA가 던지는 대부분의 에러들은 RunTimeException을 상속하는 언체크 에러로 트랜잭션이 롤백됩니다. 하지만 아래와 같이 일부 경우에는 JPA가 체크 예외를 던지게 됩니다. SQLException: JPA의 내부 구현이 JDBC를 사용하므로, SQL 문이 잘못되었거나 데이터베이스에 문제가 발생했을 때 SQLException이 발생할 수 있습니다.EntityExistsException: JPA에서 새로운 엔티티를 저장하려 할 때, 동일한 ID를 ..
프록시의 PK만 조회하면, 1+N 쿼리 문제가 터지지 않는다? https://praaay.tistory.com/6 xToOne 관계 조회 API 성능 최적화추가, 수정 API 보다도 조회 API가 성능에 가장 민감한 만큼 JPA를 사용할 때 조회 API의 성능을 최적화하는 방법을 단계별로 정리하려 합니다. 주문과 배송정보 그리고 회원을 조회하는 API를 만들praaay.tistory.com 위 글에도 정리했지만, 조회 API에서 엔티티가 지연 로딩으로 설정되었다면 1+N 쿼리가 나가는 문제를 조심해야 합니다.특히 아래 코드와 같이 엔티티를 DTO로 변환하는 과정에서 프록시 객체에 접근하는 경우라면 프록시 객체가 초기화되면서 1+N 쿼리가 나가는 문제가 발생합니다. 하지만 1+N 쿼리가 나갈 것이라 예상했던 상황에서 1+N 쿼리가 나가지 않았던 경험을 이야기해보려 합..
유연함을 위해 Custom Result 타입을 사용하자 API 스펙 변경에 유연하게 대응해야 합니다.컬렉션 그 자체로 반환하지 말고 커스텀 타입으로 한 번 감싸서 반환합시다. 아래 코드로 살펴봅시다. @GetMapping()public ResponseEntity> getAllRooms() { List rooms = roomService.getAllRooms(); List collect = rooms.stream() .filter(m -> !m.isDeleted()) .map(m-> RoomResponseDTO.from(m)) .toList(); return ResponseEntity.ok().body(collect);} 엔티티 자체를 API Response에 노출하지 않고, Room ..