본문 바로가기

JPA

(38)
[JPA] ID 생성 전략 ✏️ @GeneratedValueJPA에서 ID를 자동 생성하는 방법에는 4가지 전략이 있다.각 전략은 @GeneratedValue(strategy = GenerationType.XXX)로 지정할 수 있다. 📌 1. AUTO (기본값)@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id; ✅ 특징기본값으로 사용됨 (명시하지 않으면 AUTO가 적용됨).데이터베이스에 따라 적절한 전략을 자동 선택.보통 MySQL은 IDENTITY, H2나 Oracle은 SEQUENCE로 자동 선택됨.🛠 예제: MySQL vs H2데이터베이스AUTO 전략이 선택하는 기본값MySQL, MariaDBIDENTITY (AUTO_INCREMENT 사용)H2, Ora..
[JPA] 💼 PersistentBag 💼 PersistentBagPersistentBag은 Hibernate에서 제공하는 컬렉션 타입 중 하나로, @OneToMany 또는 @ManyToMany 관계에서 사용되는 List 타입의 컬렉션을 관리하기 위한 구현체이다. 이 컬렉션은 지연 로딩(lazy loading)과 변경 감지 기능(dirty checking)을 지원하며, JPA 엔티티에서 List 타입의 필드를 사용할 때 Hibernate가 자동으로 변환하는 컬렉션 타입이다.🤔 PersistentBag이 언제 사용될까?✅ @OneToMany 관계에서 List를 사용할 때@Entitypublic class Member { @Id @GeneratedValue private Long id; private String nam..
[Spring Data JPA] 나머지 기능들 Specifications (명세)책 도메인 주도 설계(Domain Driven Design)는 SPECIFICATION(명세)라는 개념을 소개 스프링 데이터 JPA는 JPA Criteria를 활용해서 이 개념을 사용할 수 있도록 지원  술어(predicate)참 또는 거짓으로 평가AND OR 같은 연산자로 조합해서 다양한 검색조건을 쉽게 생성(컴포지트 패턴)예) 검색 조건 하나하나스프링 데이터 JPA는 org.springframework.data.jpa.domain.Specification 클래스로 정의명세 기능 사용 방법public interface MemberRepository extends JpaRepository, JpaSpecificationExecutor {}JpaSpecificationEx..
[Spring Data JPA] 구현체 분석 스프링 데이터 JPA 구현체 분석스프링 데이터 JPA가 제공하는 공통 인터페이스의 구현체 org.springframework.data.jpa.repository.support.SimpleJpaRepository@Repository @Transactional(readOnly = true) public class SimpleJpaRepository ...{ @Transactional public S save(S entity) { if (entityInformation.isNew(entity)) { em.persist(entity); return entity; } else { return em.merg..
[Spring Data JPA] WEB 확장 기능, 페이지 1처리 코드 구현 Web 확장 - 도메인 클래스 컨버터HTTP 파라미터로 넘어온 엔티티의 아이디로 엔티티 객체를 찾아서 바인딩  **도메인 클래스 컨버터 사용 전** @RestController@RequiredArgsConstructorpublic class MemberController { private final MemberRepository memberRepository; @GetMapping("/members/{id}") public String findMember(@PathVariable Long id) { Member member = memberRepository.findById(id).get(); return member.getUsername(); } @Po..
[Spring Data JPA] Auditing Auditing엔티티를 생성, 변경할 때 변경한 사람과 시간을 추적하고 싶으면? 등록일수정일등록자수정자순수 JPA 사용하여 등록일, 수정일 적용해보자.@MappedSuperclass@Getterpublic class JpaBaseEntity { @Column(updatable = false) private LocalDateTime createTime; private LocalDateTime updateTime; @PrePersist public void prePersist() { this.createTime = LocalDateTime.now(); this.updateTime = LocalDateTime.now(); } @PreUpdate ..
[Spring Data JPA] 사용자 정의 리포지토리 구현 사용자 정의 리포지토리 구현스프링 데이터 JPA 리포지토리는 인터페이스만 정의하고 구현체는 스프링이 자동 생성을 한다. 스프링 데이터 JPA가 제공하는 인터페이스를 직접 구현하면 상속을 받아야 하니 구현해야 하는 기능이 너무 많다. 다양한 이유로 인터페이스의 메서드를 직접 구현하고 싶다면? JPA 직접 사용('EntityManager')스프링 JDBC Template 사용MyBatis 사용데이터베이스 커넥션 직접 사용 등등...Querydsl 사용1. 사용자 정의 인터페이스 public interface MemberRepositoryCustom { List findMemberCustom();} 2. 사용자 정의 인터페이스 구현 클래스@RequiredArgsConstructorpublic class..
[Spring Data JPA] JPA Hint & Lock JPA HintJPA Hint는 Java Persistence API에서 쿼리 실행 시 추가적인 힌트를 제공하여 동작을 커스터마이즈하거나 성능 최적화를 돕는 기능JPA 쿼리의 동작 방식을 유연하게 제어하거나, 특정 데이터베이스 벤더에 특화된 설정을 추가하는 데 사용된다. (SQL 힌트가 아니라 JPA 구현체에게 제공하는 힌트) 지금까지 JPA Hint의 뜻과 사용 용도를 알아보았고, 이제부터는 사용 방법에 대해서 알아보자. 쿼리 힌트 사용 @QueryHints(value = @QueryHint(name = "org.hibernate.readOnly", value = "true")) Member findReadOnlyByUsername(String username); 쿼리 힌트 사용 확인@Testpubli..
[Spring Data JPA] @EntityGraph 엔티티 그래프(Entity Graph)JPA(EntityManager)나 Hibernate에서 제공하는 기능으로, 엔티티를 조회할 때 연관된 엔티티를 어떤 방식으로 가져올지 정의하는 방법이다. 이를 통해 명시적으로 패치 전략(Fetch Strategy)을 설정하고, 필요에 따라 지연 로딩(Lazy Loading)과 즉시 로딩(Eager Loading)을 제어할 수 있다. 엔티티 그래프를 사용하는가?N+1 문제 해결:JPA의 기본 설정에서 연관 엔티티는 지연 로딩(FetchType.LAZY)으로 설정한다.필요 시 연관된 데이터를 쿼리하는데, 다수의 추가 쿼리가 발생해 성능 문제가 생길 수 있다.이를 엔티티 그래프로 해결할 수 있다.JPQL 대체:복잡한 JPQL을 사용하지 않고, 엔티티 그래프를 활용해 간결..
[Spring Data JPA] 벌크성 수정 쿼리 벌크성 쿼리벌크성 쿼리(Bulk Query)란 데이터베이스에서 한 번의 실행으로 대량의 데이터를 삽입, 수정, 삭제하거나 조회하는 쿼리를 의미한다.주로 많은 데이터를 효율적으로 처리하기 위해 사용되며, 데이터 처리 속도를 높이고 시스템 리소스를 절약하는 데 유용하다.예시로 모든 직원의 연봉을 10% 인상하는 쿼리를 짜야 한다면, 직원들을 하나씩 끌어서 10% 씩 인상하는 것보다는 DB에서 업데이트 쿼리를 한번만에 끝내고 커밋하는 것이 효율적일 것이다. 먼저 순수 JPA를 사용하여 벌크성 수정 쿼리를 처리하는 방법을 알아보자. JPA를 사용한 벌크성 수정 쿼리public int bulkAgePlus(int age) { int resultCount = em.createQuery("update Membe..