JPA 프록시의 field 접근과 get메서드 접근
2022. 5. 4. 19:51
JPA
문제 서비스 테스트는 성공하는데 API 요청 테스트는 실패하는 현상이 발생했다. 상황 설명 댓글을 작성한다. 대댓글을 작성한다. 대대댓글을 작성하면 대댓글로 작성되어야 한다. 3번이 문제 상황이다. 3번을 서비스 레어어에서 테스트 코드로 테스트할 때는 정상 동작했다. 하지만, API 요청 테스트를 하면 실패했다. 실패했다는건 아예 작성이 되지 않는 상황이었던 것이다. 원인 트랜잭션과 하이버네이트 프록시가 원인이었다. 하이버네이트 프록시 원인 하이버네이트 프록시는 아래와 같은 구조를 기진다. 동작 과정을 살펴보자. getName() 요청 시 프록시 객체의 타겟은 null이다. 진짜 객체에서 가져오도록 영속성 컨텍스트에 요청한다. 영속성 컨텍스트에 없으면 DB 조회를 한다. 실제 엔티티를 생성한다. 프록시는..
테스트 코드 작성 시 데이터베이스 초기화 하는 방법
2022. 3. 26. 19:40
JPA
테스트 코드 작성 시 데이터베이스 초기화 하는 방법 이전까지 테스트 코드 작성 시 데이터베이스 초기화 방법 데이터베이스를 초기화 해야하는 이유는 각각의 테스트는 독립된 환경에서 검증이 되어야 하기 때문이다. 테스트 코드를 작성하면 각 테스트마다 초기화된 데이터 베이스로 테스트 하기 위해 데이터 베이스를 초기화 해주어야 한다. 그 때 나는 보통 repository.deleteAll()을 사용했었다. 이전에는 몰랐는데 이번 프로젝트를 하면서 고민을 하게되며, 단점과 다른 방법을 알게 되었다. 이전 방법의 단점 repository.deleteAll()의 단점은 테스트 코드가 프로덕션 코드에 의존하게 되는 것이다. 프로덕션 코드에 의존하게 되면, repository가 변경될 경우 테스트 코드에 의존 역시 변경되..
JPA 기본키 전략을 뭘 사용해야 할까?
2022. 3. 26. 13:18
JPA
기본키 전략은 뭘 사용해야 할까?(블로깅) Identity 전략 vs Sequence 전략 Identity 전략 auto-increment를 사용하기 때문에 데이터베이스에 insert 쿼리가 실행이 되어야 ID값을 알 수 있다. 그래서 JPA에서는 persist()시점에 즉시 insert 쿼리를 실행하고 데이터베이스에서 식별자를 조회하게 된다. 즉, 쓰기 지연의 이점을 누릴 수 없다. Sequence 전략 시퀀스 전략은insert 쿼리와 상관없이 데이터베이스에서 시퀀스를 만들어서 그 시퀀스를 호출해서 사용하기 때문에 insert 쿼리가 나가지 않아도 ID를 생성할 수 있다. 이게 가능한 이유는 JPA가 데이버베이스에 있는 시퀀스를 내부적으로 조회하는 기능이 있기에 가능하다. 즉, 쓰기 지연의 이점을 누릴..
JPA에서 영속화라는 의미는 뭘까?
2022. 3. 25. 12:23
JPA
JPA에서 영속화라는 의미는 뭘까? 팀 사이드 프로젝트를 하던 중 JPA(ORM)을 사용하는 이유에 대해 이야기를 하다가 한 분이 persist, 영속화라는 의미에 대해 고민을 하시고, 이야기를 하게 되었다. JPA는 왜 Java Persistence Api라는 이름을 지었을까? Persistence 사전적 의미는 지속되다라는 의미가 있다. 엔티티 매니저의 persist() 메서드가 있다. save라고 해도될텐데 말이다. 이유는 정의하기 나름일 수도 있지만, 나는 간단하게 flush, commit 단계가 존재하고, 영속성 컨텍스트에 영속화 하는 것이기 때문에 persist()라고 네이밍 했을 것이라고 했다. save는 persist, flush, commit을 모두 포함하는 것이기 때문이다. 팀원 분의 ..
ORM(JPA)를 왜 사용할까?
2022. 3. 24. 00:02
JPA
ORM을 왜 사용하는가? SQL 의존적 개발 객체지향은 객체를 기반으로 개발을 해야하는데 관계형 데이터베이스를 사용하기 때문에 반복적인 SQL 작업을 해야한다. 패러다임의 불일치를 해결하자. 상속 객체는 상속관계가 있지만 데이터베이스는 없다. 출처 : 스프링 핵심 원리 - 기본편 하지만 위의 그림처럼 데이터베이스도 슈퍼타입 서브타입의 관계로 상속과 비슷한 구조로 설계할 수는 있다. 그렇다면 이제 어떤 부분이 불일치가 될까? 각각의 테이블에 따른 조인 SQL을 작성하고 각각의 객체에 매핑을 해줘야 한다. Album을 조회한다고 가정 해보자. 각각의 테이블에 따른 조인 SQL 작성 매핑할 각각의 객체 생성 이런 과정을 반복하게 된다. 이게 왜 문제가 될까? 만약 데이터베이스를 사용하지 않고 자바 컬렉션에 저..
JPA 영속성 컨텍스트가 뭘까?
2021. 10. 18. 00:01
JPA
JPA 영속성 컨텍스트에 관하여 클라이언트 요청부터 DB까지 동작하는 로직 웹 애플리케이션에 클라이언트 요청이 들어오면 EntityMangagerFactory 는 EntityManager 객체를 생성하게 됩니다. 각각 생성된 EntityManger 객체는 DB 커넥션 풀과 연결되게 됩니다. 영속성 컨텍스트 엔티티를 영구 저장하는 환경입니다. DB에 저장하는 것이 아니라 영속성 컨텍스트 에 저장하는 것입니다. EntityManager.persist(entity); 와 같이 엔티티를 EntityManager에 저장하여 사용할 수 있다는 것입니다. 즉, 'EntityManager' 를 통해 영속성 컨텍스트 에 접근하는 것입니다. 더 쉽게 이해하려면 EntityManager -> Persisten..
JPA 지연로딩과 즉시로딩
2021. 5. 16. 12:10
JPA
지연로딩과 즉시로딩이란? 지연로딩(LAZY) 연관된 엔티티를 한방 쿼리로 조회 하지 않고, 필요한 시점에 따로 쿼리를 만드는 것을 뜻 합니다. 매번 연관된 모든 데이터를 조회할 필요가 없을 경우 유용 합니다. 즉시로딩(EARGER) 매번 연관된 엔티티가 모두 필요할 경우 한방 쿼리를 만드는 것을 뜻 합니다. 즉, 매번 조인 쿼리가 나가게 됩니다. 즉시로딩과 지연로딩 예제 Beverage와 BeverageBrand는 N : 1 음료 엔티티( 사이다, 콜라와 같은 음료 종류 엔티티 ) package dugi; import javax.persistence.*; @Entity public class Beverage { @Id @GeneratedValue(strategy = GenerationType.IDENTI..