본문 바로가기

Spring/JPA19

JPA에서 Lombok 사용시 주의할 점 🤣 배경 프로젝트를 마치고 나면 항상 코드 인스펙션 과정을 통해 프로그램에 대한 취약점이나 장애가 있는지 확인을 하게 되는데, 간혹 equals와 hashcode가 구현되지 않은 엔티티에 대해 경고로 지적을 당하게 되는 경우가 종종 있다. 처음에는 Lombok에서 제공하는 @EqualsAndHashCode를 써서 간편하게 해결하려고 했다. 그런데 나중에 프로그램 사용 중에 문제가 발생하면서 Lombok 사용이 문제라는 것을 알게 되었고, 다른 문제는 없을지 JPA에 Lombok을 사용할 때 주의할 점에 대해 알아보게 되었다. 문제점 1. HashMap, HashSet 사용에 문제가 발생한다. - Shiba 엔티티 @Entity @Table(name = "tb_shiba_holic") @EqualsAndH.. 2023. 12. 30.
[JPA] PK가 아닌 필드에 Auto Increment 사용하기 ✍ 배경 PK를 String으로 사용하는 테이블이 있는데, 별도 필드에 AUTO INCREMENT를 적용해야 하는 경우가 생기게 되었다. 흔하지 않은 상황이지만 JPA를 사용할 때 이런 경우 어떻게 해결해야 할지 찾아본 내용을 공유하고자 한다. 🔎 테스트 환경 - MariaDB 10.6 - HeidiSQL - Spring Boot 2.7.2 MySQL/MariaDB 외에 다른 데이터베이스를 사용하는 경우는 해당 방식이 적용되지 않을 수 있다는 점을 알아뒀으면 좋겠다. 하지만 방식은 거의 유사할거라고 생각한다. 🔎 공통 필자가 찾아낸 방식은 2 가지 인데, 이 방식들은 모두 공통적으로 처리해야 하는 부분이 있었다. 1. 데이터베이스에 시퀀스를 무조건 등록해야한다. create sequence SHIBA_S.. 2023. 12. 9.
Querydsl Paging & Count Query 최적화 fetchResults() - Deprecated 기존에는 fetchResults()를 사용하여 페이징 처리할 때 개발자가 별도의 count 쿼리를 작성하지 않아도 돼서 편리했다. 하지만 Querydsl 5.0 버전부터 fetchResults는 Deprecated 되었다. fetchResults()는 개발자가 작성한 select 쿼리를 기반으로 count 용 쿼리를 내부에서 만들어서 실행한다. 단순 쿼리에서는 동작에 문제가 없었으나, 다중 그룹 쿼리(group By) 등 복잡한 쿼리에서는 잘 작동하지 않는다. 사용자들에게는 fetch() 후 결과를 count 하여 사용하라는 대안을 제시한다. Querydsl에서 페이징 처리를 할 때 다음과 같이 보통 Pageable를 파라미터로 받고 pageSize, o.. 2023. 11. 11.
[JPA] orphanRemoval 옵션을 사용할 때 Update 주의사항 😂 배경 프로젝트 개발 중 특정 엔티티에 10개가 넘는 필드를 업데이트를 해달라는 비즈니스 요구사항이 있었다. 그래서 10개가 넘는 필드를 각각 업데이트하는 메서드를 작성했는데.. 보기에 별로 좋아 보이지 않았다. 필자는 JPA의 save() 메서드가 통해 저장과 변경에 대한 기능을 한 번에 제공하고 있다는 걸 알고 있었다. 그래서 빌더 패턴으로 기존 ID, 값, 변경된 값을 추가한 새로운 엔티티를 만들어서 save()를 통해 업데이트하는 게 보기에도 좋고 효율적으로 보였다. 생각대로 코드를 작성하고 테스트 한 뒤 나름 결과에 만족했다. 그러던 어느 날 운영 팀에서 연락이 온다. "업데이트를 했더니 연결된 데이터가 다 사라졌는데요?" "????" 운영 중에 클라이언트가 업데이트를 했는데, 데이터가 다 사.. 2023. 10. 28.
@Transactional 특징, 사용방법, 주의점 😤 배경 스프링에서 트랜잭션 처리가 필요한 경우, 나는 간단하게 JPA와 함께 @Transactional 어노테이션을 클래스 혹은 메서드에 설정해 왔다. 그러던 중 최근 운영 중인 서비스에서 Transaction Lock 이슈가 발생하면서 문득 이렇게 막 사용하는 게 옳은 일인가를 고민하게 되었고, 조사 및 정리 차원에서 해당 내용에 대해 작성하게 되었다. 해당 포스팅에서는 @Transactional 개념과 원리보다는 특징, 사용 방법, 주의점에 대해서 간단하게 설명하고자 한다. 1. 특징 @Transactional은 다음과 같은 특징을 가지고 있다. - AOP를 통해 구현되었다. - 어노테이션이 선언된 클래스에 트랜잭션이 적용된 프록시 객체가 생성된다. - CheckedException 또는 예외가 없.. 2023. 8. 15.
Spring Boot 3.0 QueryDsl Maven 설정하기 ✏️ 배경 토이 프로젝트에서는 최신 환경으로 해보고 싶어서 Spring Boot 3.0 버전과 Spring Framework 6을 사용해서 개발을 진행하고 있었는데, 복잡한 동적 쿼리를 해결하기 위해 Querydsl 도입하기 위해 적용하는 시점에 설정 후 컴파일에 계속해서 실패하는 상황이 발생했다. 스프링 부트 3.0 Maven 환경에서 Querydsl을 적용하는 방법에 대해서 간단히 공유하고자 한다. Gradle 환경이라면 다른 포스트를 찾아보는 걸 권장한다. 🔎 AS-IS 보통 Querydsl 설정을 검색해서 보면 아래와 같은 설정을 하라는 글을 많이 접하게 된다. com.querydsl querydsl-apt 5.0.0 provided com.querydsl querydsl-jpa 5.0.0 com.. 2023. 4. 9.
JPA 동일 트랜잭션에서 update와 insert 동시에 수행할 때 문제 해결하기 (쿼리 실행 순서 문제) unique 제약이 걸린 필드를 '동일한 트랜잭션' 내에서 수정하고 저장해야 하는 경우가 있었다. 그래서 필드를 먼저 수정(update)하고 새롭게 저장(insert)하면 순서대로 처리되지 않을까? 예상하며 코드를 작성했다. 하지만 예상과 다르게 예외가 발생하며 실패했고, 이후 원인을 찾아서 해결하게 되었다. 이 문제를 해결했던 내용을 비슷한 상황을 재현한 간단한 테스트 코드를 활용해 공유하고자 한다. 🐕 테스트 환경 Shiba.java (엔티티 내용 중 일부) ... @Column(unique = true) private String identification; public void updateIdentification(String identification) { this.identification =.. 2023. 2. 5.
JPA @Where 일괄 조회 사용법 및 문제점과 해결방안 프로젝트 진행 중, 엔티티 특정 필드의 상태가 'N'인 모든 데이터가 조회되지 않도록 일괄 적용할 방법이 필요하여 @Where를 적용하게 되었고 사용 방법 및 적용 이후 발생한 문제와 다양한 테스트 경험에 대해 공유하고자 한다. - 사용 방법 @Where의 사용방법은 굉장히 단순하다. 엔티티 클래스에 org.hibernate.annotations 패키지의 @Where를 클래스 단위에 작성하면 된다. (해당 어노테이션은 클래스뿐 아니라 메서드, 필드 단위도 설정은 가능하지만 테스트를 진행하지는 않았다.) 만약, 입양되지 않은 상태의 시바견 데이터는 항상 조회 조건에 포함이 안되었으면 좋겠다.라고 한다면 is_adopted 필드의 상태가 'N'이 아닌 데이터만 조회할 수 있도록 설정한다. @Where(cla.. 2023. 1. 24.