Spring/JPA 심화

JPA가 해결하는 근본적인 문제

JuNo_12 2025. 6. 25. 20:27

문제의 출발점

안녕하세요, 오늘은 JPA가 왜 필요한지에 대해 이야기해보려고 합니다.

 

우리 개발자들은 객체지향 프로그래밍을 합니다. 추상화, 캡슐화, 상속, 다형성 같은 원칙들을 지키면서 객체를 중심으로 아키텍처와 모델링을 하죠.

 

그런데 여기서 문제가 생깁니다.


태생적인 간극

데이터베이스에는 객체라는 개념이 존재하지 않습니다.

관계형 데이터베이스는 순수하게 데이터를 저장하는 곳입니다. 테이블과 컬럼, 그리고 관계만 있을 뿐이죠.

객체지향 세계: Member → Team (참조 관계)
관계형 DB 세계: member 테이블 → team_id (외래키)

완전히 다른 두 세계입니다.


SQL로는 한계가 있었다

이 간극을 메우기 위해 우리는 SQL이라는 언어를 사용했습니다.

하지만 이 간극은 쉽게 좁혀지지 않았어요.

// 우리가 원하는 객체지향적 코드
Member member = findMember(1L);
Team team = member.getTeam();    // 자연스러운 객체 탐색
List<Order> orders = member.getOrders();

// 하지만 실제로는...
public Member findMember(Long id) {
    String sql = "SELECT m.name FROM member m WHERE m.id = ?";
    // Team은 조회 안됨! getTeam() 호출하면 NPE 발생
    // 결국 DAO 클래스를 확인해야만 안전한 코드 작성 가능
}

개발자 시간의 잘못된 배분

결국 우리는 SQL문을 관리하고 데이터들을 관리하는데 굉장한 시간과 비용을 쏟게 되었습니다.

개발자의 하루:
- 객체 모델링: 20%
- SQL 작성, 결과 매핑, DAO 관리: 80%

정작 객체를 다루는데 시간을 사용하지 못했어요.

비즈니스 가치를 만드는 핵심 로직보다는 기술적 간극을 메우는 반복 작업에 매달렸던 거죠.


JPA, 신세계의 등장

그런데 이때 JPA라는 신세계가 나타났습니다.

JPA는 이 간극을 알아서 매워주는 기술입니다.

// JPA를 사용하면
Member member = entityManager.find(Member.class, 1L);
Team team = member.getTeam();           // 안전! 지연 로딩으로 자동 조회
List<Order> orders = member.getOrders(); // 이것도 안전!

// 마치 컬렉션을 사용하는 것처럼
// SQL은 JPA가 알아서 생성해줌

진정한 객체지향 프로그래밍의 시작

JPA를 제대로 활용하면 우리는 이제 진정한 객체지향 프로그래밍을 할 수 있게 됩니다.

정확히 말하면 객체 모델링에 시간을 많이 쏟을 수 있게 되는 거죠.

JPA 이후:
- 객체 모델링과 비즈니스 로직: 80%
- 데이터 관리: 20%

데이터를 관리하는데 시간을 많이 안 써도 되니까요.


추가적인 가치들

이렇게 되면 자연스럽게 도메인 주도 설계(DDD)도 가능해집니다.

기술적 제약 때문에 포기했던 풍부한 도메인 모델을 이제 마음껏 만들 수 있어요.

@Entity
public class Order {
    @OneToMany(cascade = CascadeType.ALL)
    private List<OrderItem> orderItems;
    
    @ManyToOne
    private Member member;
    
    // 풍부한 비즈니스 로직
    public Money calculateTotalAmount() {
        return orderItems.stream()
            .map(OrderItem::getAmount)
            .reduce(Money.ZERO, Money::add);
    }
    
    public void changeDeliveryAddress(Address address) {
        if (status != OrderStatus.ORDER) {
            throw new IllegalStateException("이미 배송중인 상품은 주소 변경이 불가합니다.");
        }
        this.deliveryAddress = address;
    }
}

결론

JPA는 단순한 데이터 접근 기술이 아닙니다.

객체지향 프로그래밍을 제대로 할 수 있게 해주는 혁명적인 도구입니다.

이제 우리는 SQL과 테이블 구조를 고민하는 대신, 어떻게 하면 더 좋은 객체 모델을 만들 수 있을까를 고민할 수 있게 되었습니다.

그리고 그것이야말로 개발자가 진짜 해야 할 일이겠죠.