본문 바로가기
Back-End/Spring

데이터베이스의 엔티티(Entity)에 대한 고찰, 그리고 JPA의 @Entity 어노테이션

by blackjack_96 2024. 4. 12.

JPA관련 프로젝트를 하면서 느끼는 것이지만,

공부를 하며  "그런가보다" 하면서 무심코 넘어갔던 지식들이 많았음을 느끼고 반성합니다.

 

데이터베이스에서의 엔티티(Entity) 개념,

그리고 JPA로 프로젝트를 진행하면서 아무렇지 않게 붙여왔던

@Entity 어노테이션이 어떠한 의미를 지니고 있는 지 생각해보았습니다.

 

데이터베이스에서의 엔티티(Entity)

 데이터베이스의 엔티티(Entity) 정의는 영미권 커뮤니티에서 다음과 같은 의미로 많이 사용합니다.

 

In a database, an entity is a piece of data that can be uniquely identified

 

 좀 더 이해하기 쉽게 설명을 해 보겠습니다.

 우리는 '학생'의 정보를 데이터베이스 관리 시스템(DMBS)에 저장해 관리하기를 원하는 상황입니다.

 

 그리고 하나의 학생 당,

 학생의 이름, 학생의 학번, 학생의 학년, 학생의 성별, 학생의 전화번호

 이렇게 총 5개의 정보를 저장하고 싶습니다.

 

 즉 우리가 학생 한명 당, 저장해야 할 정보는 다음과 같다고 볼 수가 있습니다.

 

 

 

학생 한 명 → {이름, 학번, 학년, 성별, 전화번호}

 

 

 

 물론 실 세계에서 학생에게는, 더욱 많은 속성(attributes)들이 존재합니다.

 학생 보호자 전화번호, 입학 년도, 졸업 예정 년도 등등..

 저장하기 원하는 정보 보다 실제로는 더욱 많은 속성들이 존재할 것입니다. 

 

 

 하지만 그것들은 우리의 관심사가 아닙니다.

 우리가 원하는 정보는 오직 위 다섯 개 정보 뿐이고, 다른 정보들은 원하지 않기 때문에

 위 다섯 개의 정보만을 저장하는 것이죠.

 

 한 마디로, 우리는 그저 하나의 학생 이라는 정보를 다음의 묶음으로 저장하고자 하는 것입니다.

 

학생 한 명 → {이름, 학번, 학년, 성별, 전화번호}

 

 이렇게 실제 세계(Real Environment)에 존재하는 하나의 독립적인 객체를 대상으로,

 우리가 관심있어 하는 정보들을 한데 엮어서,

 데이터베이스에 저장하는 하나의 단위로 정의하였을 때에,

 이 하나의 단위가 바로 엔티티(Entity)라는 것입니다.

 

 

데이터베이스 테이블

 

위 테이블에는 총 3개의 학생 정보가 저장이 되어 있습니다.

저장되어 있는 하나 하나의 데이터가 바로 '학생'이라는 엔티티(Entity)인 것입니다.

즉, 위 테이블에는 총 3개의 엔티티(Entity)가 저장되어 있습니다.

 

아주 간단하게 말하자면 엔티티란, "데이터베이스의 저장 대상이 되는 정보 단위"라고도 볼 수 있겠습니다.

 

영혼 없이 붙여왔던 @Entity 어노테이션

 여러 책이나 강의를 보아도,

 @Entity를 다음과 같이 설명하는 곳이 대부분입니다.

 

"JPA라는 프레임워크에서, 해당 클래스를 관리 대상 엔티티로 식별하도록 하는 어노테이션이다"

 

 꽤나 추상적이며 당연한 말입니다.

 그런데 저는 위 문장을 아무런 생각없이 그대로 받아들였기 때문에

 다음과 같은 질문에 답을 하지 못하는 상황에 직면했습니다.

 

 

"클래스에 @Entity어노테이션을 붙이지 않으면 어떻게 되나?"

 

 

 물론 바로 위에서 기술한 @Entity어노테이션의 의의만을 놓고 보면

 다음과 같이 대답을 할 수가 있습니다.

 

"클래스에 @Entity어노테이션을 붙이지 않으면,

JPA에서 해당 클래스를 관리 대상 엔티티로 식별하지 못합니다."

 

 

 이러한 대답 또한 추상적이며 당연한 말입니다.

 제가 알고 싶었던 것은, @Entity를 클래스에 붙였을 때와 붙이지 않았을 때에,

 구체적으로 어떠한 차이가 발생하는 가에 대한 내용이었습니다.

 

 JPA에는 데이터베이스 스키마 자동생성 기능이란 것이 있습니다.

 테이블을 개발자가 직접 SQL을 이용해  생성하는 대신, 

 

 스프링부트 애플리케이션이 시작될 때,

 우리가 정의한 엔티티를 저장할 수 있는 테이블을 자동으로 만들어 주는 기능이 바로,

 데이터베이스 스키마 자동생성(Database Schema Auto-Create) 기능입니다.

 

@Entity를 붙였을 때와 붙이지 않았을 때의 차이는

 위의 데이터베이스 스키마 자동생성 기능이 동작할 때 나타납니다.

 

 

@Entity라는 어노테이션이 붙은 클래스는

JPA의 관리대상으로 식별되고,

이렇게 JPA의 관리 대상으로 식별이 되고 나서야,

스프링부트 애플리케이션은 해당 클래스의 객체들을 저장해낼 수 있는 테이블을 자동으로 생성합니다.

 

즉 @Entity라는 어노테이션이 붙어있지 않은 클래스가 있다면,

데이터베이스 스키마 자동생성 기능을 켜도,

그 클래스의 객체를 저장해낼 수 있는 데이터베이스 테이블을 생성해주지 않습니다.

 

 

"@Entity가 붙은 클래스에 해당하는 엔티티가 저장될 수 있는 테이블을 자동 생성한다."

"@Entity가 붙지 않은 클래스에 해당하는 테이블은 자동생성하지 않는다."

 

@Entity의 name속성

다음과 같이 @Entity어노테이션이 붙은 엔티티가 있다고 가정해 보겠습니다.

 

@Entity(name = "MBR")
// name 속성을 지정하지 않으면, 클래스의 이름으로 자동 등록된다.
class Member {

    ...

}

 

 이렇게 되어있을 때에, Member클래스의 인스턴스를 다음 코드를 통해 영속화 하였을 때에,

 

Member member = new Member()

em.persist(member)

 

이 member라는 인스턴스는 "MBR"이라는 이름의 테이블로 삽입이 됩니다.

왜냐하면, 이 Member라는 클래스가 @Entity어노테이션에 의하여

MBR이라는 이름의 데이터베이스 테이블과 매핑이 되었기 때문입니다.