DB 접근/JPA ( Java Persistence API )

[JPA] 페러다임 불일치 문제 [객체 관계형 데이터베이스]

JABHACK 2025. 1. 2. 08:28

객체와 관계형 데이터베이스

📌 객체는 클래스를 통해 만들어지며 속성(field)와 기능(method)를 포함하며 관계형 데이터베이스는 데이터를 테이블 형식으로 표현하며 각 테이블은 열(column)과 행(row)으로 구성된다.

 

객체 지향 언어 Java

  • 객체를 저장할 수 있는 다양한 종류의 Database
    1. RDB(무결성, 일관성)
    2. NoSQL
    3. File
    4. 기타 등등..
  • 관계형 데이터베이스와 객체 지향의 패러다임 불일치 문제가 발생한다.

 

관계형 DB에 객체 저장 시 발생하는 문제점

 

1. 관계형 DB와 객체 간의 구조적 차이

  1. 객체 지향 vs. 관계형 모델:
    • 객체지향 언어(Java, Python 등)는 객체를 중심으로 설계되며, 상태(필드)와 행동(메서드)을 결합.
    • 관계형 데이터베이스는 테이블과 행(row)을 기반으로 데이터를 저장하며, 테이블 간 관계(Primary Key, Foreign Key)를 정의.
  2. 데이터 표현 차이:
    • 객체는 복잡한 데이터 구조를 포함할 수 있지만, 데이터베이스 테이블은 정규화된 단순 구조로 데이터를 저장.
  3. 매핑 복잡성:
    • 객체를 RDB 테이블에 맞게 변환(매핑)하는 과정에서 많은 문제가 발생.

 

 

2. CRUD 반복 문제

객체 지향 프로그래밍에서 관계형 데이터베이스와 상호작용할 때 리소스별 CRUD 작업을 반복적으로 작성해야 하는 문제가 자주 발생합니다.

예제 상황

  • 애플리케이션에 User, Product, Order라는 객체가 존재.
  • 각각의 객체에 대해 CRUD(Create, Read, Update, Delete) 작업이 필요.

문제점

  1. 반복적인 SQL 작성:
    • 각 리소스마다 유사한 SQL 쿼리(CRUD)를 작성해야 함.
    • 예:
      • INSERT INTO users ...
      • SELECT * FROM users ...
      • UPDATE users SET ...
      • DELETE FROM users WHERE ...
  2. 코드 중복:
    • 객체를 저장하거나 읽을 때 매번 SQL을 수동으로 작성해야 하며, 이 과정에서 비슷한 코드가 반복됨.
  3. 유지보수 어려움:
    • 리소스가 추가되거나 변경될 때, 관련 SQL이나 매핑 코드를 모두 수정해야 함.
  4. 변경에 따른 리스크:
    • 데이터베이스 스키마가 변경되면, 관련된 모든 CRUD 코드를 수정해야 하므로 버그 발생 가능성이 증가.

 

INSERT, UPDATE, SELECT, DELETE

  • Java Object to SQL
  • SQL to Java Object

 

 

 

패러다임 불일치 문제

📌 객체에서는 상속과 다형성을 통해 객체 관계를 표현할 수 있지만 RDB는 이 개념을 직접 지원하지 않고 별도 매핑이 필요하다. 또한, 객체는 참조로 관계를 표현하고 RDB는 JOIN을 사용하여 관계를 결합한다.

 

 

상속

DB는 상속관계가 없다.

관계형 DB에서는 Data를 슈퍼타입, 서브타입 관계로 설정한다.

  • Tutor 저장

  • Tutor 조회

  • 각각의 객체별로 JOIN SQL 작성, 객체 생성 및 데이터 세팅이 필요하다.
  • 까다롭기 때문에 DB에 저장할 객체는 상속 관계를 사용하지 않는다.

 

연관관계

📌 테이블의 연관관계는 외래 키를 사용한다.

 

📌  객체의 연관관계는 참조를 사용한다

 

연관탐색

📌 객체 지향 언어에서 데이터와 동작을 함께 캡슐화하는 방식과, RDB가 데이터를 정규화된 테이블에 관계 중심으로 저장하는 방식의 차이에서 발생한다. 이로 인해 객체를 데이터베이스에 저장하거나 조회할 때 복잡한 매핑과 변환이 필요해지고 코드의 복잡성과 개발자의 부담이 증가한다.

**정규화(Normalization)**는 관계형 데이터베이스 설계에서 데이터를 중복 없이 체계적으로 저장하기 위해 데이터를 여러 테이블로 나누고, 각 테이블 간에 적절한 관계를 정의하는 과정입니다.

 

  1. 상속과 유사한 관계의 데이터베이스를 구축한 경우 상위 아키텍처는 다음 계층을 믿고 사용가능해야한다.
  2. Entity가 믿고 쓸 수 있는 상속인지 확인해야한다. productRepository.findById();의 신뢰성 확인이 필요하다.
  3. 매번 신뢰성 확인이 필요하니 SQL Query가 굉장히 무거워진다.
  4. 진정한 의미의 계층 분할이 어렵다.
  5. 필요 없는 데이터도 항상 함께 조회된다. (연관된거 싹다 들고온다)

 

 

객체의 비교

Product product1 = productRepository.findById(productId);
Product product2 = productRepository.findById(productId);

product1 == product2; // false
  • 데이터는 같지만, 새로운 인스턴스기 때문에 객체의 주소값이 다르다.

 

 

결론

  • 객체 지향적으로 설계하면 코드가 점점 복잡해진다.
    • SQL Query, Mapping이 까다롭다.
  • Collection처럼 객체가 관리된다면 편리해진다.
// Entity 신뢰 가능
Product product = list.get(productId);
Category category = product.getCategory();

// 비교 가능
Product product1 = list.get(productId);
Product product2 = list.get(productId);

product1 == product2; // true
  • JPA(Java Persistence API) 등장
    • 마치 Java의 Collection처럼 객체를 저장하고 사용할 수 있게 해준다.
    • JPA를 사용하면 패러다임 불일치 문제를 모두 해결할 수 있다.

 

'DB 접근 > JPA ( Java Persistence API )' 카테고리의 다른 글

[JPA] Spring Data JPA  (0) 2025.01.07
[JPA] 연관관계 Mapping  (0) 2025.01.06
[JPA] 영속성 컨텍스트  (2) 2025.01.04