본문으로 건너뛰기

Entity Definition

Overview

ElastiCORE DSL은 YAML 기반의 도메인 모델 정의 언어로, entity, dto, enumeration, repository, transaction port를 정의하여 Java 코드를 자동 생성합니다. 해당 정의 파일들은 ./resources/blueprint/{도메인명} 디렉토리 하위에 yml 확장자를 가지는 파일명으로 자유롭게 정의하여 기술한다. 되도록 모델 타입별 파일을 만들어 타입 별로 해당 파일에 아래 모델 정의를 기술. ex) entity.yml, dto.yml 자세한 환경설정 관련 내용은 env.yml 환경설정를 참조

Basic Structure

entity:
EntityName:
meta: entity [annotations]
fields:
fieldName: fieldType [annotations] -- 주석

Meta Annotations

  • entity: 기본 엔티티 선언
  • @abstract: 추상 엔티티 (상속 전용)
  • @extend(ParentEntity): 엔티티 상속
  • @expose(n): REST API 노출 및 페이지 크기 설정 (Controller, Service, SearchDTO 생성)
  • @service(n): 서비스 레이어만 생성 및 페이지 크기 설정 (Controller 제외, Service, SearchDTO 생성)
  • @audited: JPA Envers 감사 대상
  • @dto: DTO 생성 가능 표시
  • @pageable: 페이징 처리 지원
  • @embeddable: JPA Embeddable 엔티티
  • @table(tableName): 테이블명 지정
  • @java(fullClassName): 생성될 Java 클래스명 지정
  • @Index(name="idx_name", columnList="col1,col2"): 인덱스 정의

Field Annotations

  • @id: 기본키
  • @sequence: 자동 증가 시퀀스
  • @genid: 사용자 정의 ID 생성기 (env.yml 설정 참조)
  • @GeneratedValue: JPA 자동 생성값
  • @length(n): 문자열 최대 길이
  • @default(value): 기본값 설정
  • @search(like|eq|between|in): 검색 조건 설정
  • @updatable(false): 수정 불가능 필드
  • @ref(path): 다른 필드 참조
  • @dtype(type): DTO 타입 명시
  • @cascade(ALL|PERSIST|MERGE|REMOVE): 연관관계 cascade 설정
  • @relation(mappedBy="fieldName"): 연관관계 매핑
  • @notaudited: 감사 제외 필드
  • @Column(name="col_name", length=n): JPA 컬럼 매핑
  • @env:annotationName: 환경설정 어노테이션 참조

For detailed information on field annotations, see 어노테이션 가이드.

JPA Relationship Annotations

  • @OneToMany(mappedBy="fieldName"): 일대다 관계
  • @ManyToOne: 다대일 관계
  • @ManyToMany: 다대다 관계
  • @OneToOne: 일대일 관계

Spring Data JPA 어노테이션

  • @jpa:org.springframework.data.annotation.CreatedDate: 생성일시 자동 설정
  • @jpa:org.springframework.data.annotation.CreatedBy: 생성자 자동 설정
  • @jpa:org.springframework.data.annotation.LastModifiedDate: 수정일시 자동 설정
  • @jpa:org.springframework.data.annotation.LastModifiedBy: 수정자 자동 설정

Field Types

필드 타입에 대한 상세 정보는 필드 타입 상세.

  • string(n), string(n)!: 문자열 (! = NOT NULL)
  • text: 긴 텍스트 (TEXT 타입)
  • int, Integer: 정수
  • long, Long: 긴 정수
  • double, Double: 실수
  • boolean, Boolean: 참/거짓
  • bigdecimal(precision.scale): 고정소수점 숫자 (예: bigdecimal(15.2) → @Column(precision = 15, scale = 2))
  • date: 날짜 (LocalDate)
  • datetime: 날짜시간 (LocalDateTime)
  • int[], string[]: 배열 타입
  • List<Type>: 리스트 타입
  • EnumName: 열거형 참조
  • EntityName: 엔티티 참조

Entity Examples

entity:
BaseEntity:
meta: entity @abstract
fields:
createDate: datetime @search(between) @updatable(false) @jpa:org.springframework.data.annotation.CreatedDate
createdBy: string(20) @updatable(false) @jpa:org.springframework.data.annotation.CreatedBy

AuditEntity:
meta: entity @abstract @extend(BaseEntity)
fields:
lastModifiedBy: string(20) @jpa:org.springframework.data.annotation.LastModifiedBy
lastModifiedDate: datetime @jpa:org.springframework.data.annotation.LastModifiedDate
createIP: string(20) -- 시스템 입력 IP
lastModifiedIP: string(20) -- 시스템 수정 IP

Board:
meta: entity @expose(50) @extend(AuditEntity) @Index(name="idx_board_type", columnList="board_type")
fields:
bid: long @id @sequence -- 게시판 ID
name: string(100)! @search(like) -- 게시판명
boardType: BoardType -- 게시판 타입
articles: List<Article> @dtype(List<ArticleDTO>) @OneToMany(mappedBy="board")

Article:
meta: entity @expose(50) @extend(AuditEntity)
fields:
aid: string @id @genid -- 글 ID
title: string(200)! @search(like) -- 제목
content: text -- 본문
price: bigdecimal(10.2) @search(between) -- 가격 (정밀도 10, 소수점 2자리)
board: Board @ManyToOne -- 상위 게시판
coordinates: int[] @env:integerarray -- 좌표 배열

Advanced Features

Composite Key Definition

entity:
CompositeKeyEntity:
meta: entity
fields:
key1: string @id
key2: string @id
data: string

임베디드 엔티티

entity:
Address:
meta: entity @embeddable
fields:
postNo: string(5) @Column(name="post_no", length=5)
baseAddr: string(200) @Column(name="base_addr", length=200)
detailAddr: string(300) @Column(name="detail_addr", length=300)

User:
meta: entity
fields:
userId: long @id @sequence
name: string(100)!
address: Address -- 임베디드 주소

Inheritance

entity:
Vehicle:
meta: entity @abstract
fields:
id: string @id
brand: string(50)
model: string(100)

Car:
meta: entity @extend(Vehicle)
fields:
doors: int -- 문 개수
fuelType: FuelType

Motorcycle:
meta: entity @extend(Vehicle)
fields:
engineSize: int -- 엔진 배기량

Many-to-Many Relationships

entity:
User:
meta: entity
fields:
userId: long @id @sequence
username: string(50)!
roles: List<Role> @ManyToMany

Role:
meta: entity
fields:
roleId: long @id @sequence
roleName: string(50)!
users: List<User> @ManyToMany(mappedBy="roles")

Naming Conventions

엔티티

  • 클래스명: PascalCase (Board, Article, BoardType)
  • 필드명: camelCase (boardId, createDate, lastModifiedBy)
  • 테이블명: snake_case (board, article, board_type)

ID 필드

  • 패턴: 엔티티명(소문자) + "Id" (boardId, articleId, userId)

Best Practices

  1. 상속 계층 설계: BaseEntity → AuditEntity → 구체 엔티티
  2. 검색 기능: 자주 검색되는 필드에 @search 어노테이션
  3. 인덱스 최적화: 조회 성능을 위한 @Index 설정
  4. 관계 매핑: @dtype으로 DTO 타입을 명시하여 순환 참조 방지
  5. 감사 추적: 중요한 엔티티에 @audited 적용
  6. 필드 검증: NOT NULL 필드에 ! 명시
  7. 환경 설정 활용: 공통 어노테이션을 env.yml에 정의

Important Notes

  • 순환 참조: 양방향 관계에서 @dtype 사용으로 방지
  • 성능 고려: 대용량 데이터는 페이징 처리 (@pageable, @expose)
  • 데이터 일관성: 외래키 관계는 @cascade 설정 주의
  • 검색 최적화: 복합 검색 조건은 인덱스 설계 고려