개발일지

[개발일지_safeHome] 5. sample 도메인 개발 (모델, 엔티티)

woopii 2025. 12. 14. 00:04

 

1. 명명규칙 정하기

막상 클래스를 작성하려니 테이블명을 복수로 할 것인지, 단수로 할 것인지 고민을했다.

조금 알아보니 데이터의 집합을 표시하면 s를 붙이고, 단일 개념을 의미하면, s를 안붙이는 것을 표준으로 하는 곳이 많다고 한다

그래서 다음과 같이 명명 규칙을 정했다.

 

계층 규칙 이유  예시
Entity 단수 객체 SampleEntity
Repository 단수 도메인 객체의 조회/저장 행위 SampleRepository
Port 단수 도메인 관점의 역할/행위 SamplePersistencePort
UseCase 단수 하나의 행위/유스케이스 SampleUseCase
Service 단수 서비스 SampleUseCaseImpl
Model/DTO 단수 하나의 데이터 구조 Sample
Mapper 단수 변환기 SampleMapper
Adapter 단수 특정 도메인 어댑터 SampleInboundAdapter
REST API 복수 리소스 집합 /samples
DB Table 복수 레코드 집합 samples

 

2. 모델 작성

우선 테이블 구조와 동일하게 Sample, SampleDetail 작성

예전 프로젝트에서는 audit 관련 필드 (is_deleted, created_at 등)도 모델에 포함했는데,
비지니스적으로 의미있는 데이터만 가져가는게 맞는거 같아서

이번에는 entity에만 audit 필드를 넣을 예정

 

  • Sample
package com.woopi.safehome.domain._sample.model

data class Sample(
    val id: Long,
    val name: String,
    val code: String,
    val description: String?,
    val orderNo: Int,
)

 

  • SampleDetail
package com.woopi.safehome.domain._sample.model

data class SampleDetail(
    val id: Long,
    val sampleId: Long,
    val detailValue: String?,
)

 

 

 

3. 엔티티 작성

엔티티는 data class가 아닌 그냥 class로 작성해야 한다.

이유는 아래에 따로 정리함

https://woopi1087.tistory.com/135

 

  • SampleEntity
package com.woopi.safehome.domain._sample.adapter.outbound.persistence.jpa

import jakarta.persistence.Entity
import jakarta.persistence.GeneratedValue
import jakarta.persistence.GenerationType
import jakarta.persistence.Id
import jakarta.persistence.Table
import java.time.LocalDateTime

@Entity
@Table(name = "samples")
class SampleEntity(

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Long? = null,

    var name: String,

    var code: String,

    var description: String? = null,

    var orderNo: Int = 0,

    var isDeleted: Boolean = false,
    var createdId: Long,
    var createdAt: LocalDateTime,
    var updatedId: Long? = null,
    var updatedAt: LocalDateTime? = null
)

 

 

  • SampleDetailEntity
package com.woopi.safehome.domain._sample.adapter.outbound.persistence.jpa

import jakarta.persistence.*
import java.time.LocalDateTime

@Entity
@Table(name = "sample_details")
class SampleDetailEntity (

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Long? = null,

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "sample_id", nullable = false)
    var sample: SampleEntity,

    @Column(name = "detail_value")
    var detailValue: String? = null,

    var isDeleted: Boolean = false,
    var createdId: Long,
    var createdAt: LocalDateTime,
    var updatedId: Long? = null,
    var updatedAt: LocalDateTime? = null
)

 

4. 엔티티 작성 (수정, BaseEntity 추가)

아래와 같이 entity 수정 Audit 관련 항목과 ID는 공통 항목이라서 공통엔티티 만들고, 각 도메인 엔티티가 상속받도록 수정함

무결성 관점에서 ID가 실수로 수정되는 것을 방지하기 위해서 protected set을 세팅함

 

  • BaseEntity
package com.woopi.safehome.global.`object`

import jakarta.persistence.*
import java.time.LocalDateTime

@MappedSuperclass
abstract class BaseEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Long? = null
        protected set

    @Column(name = "is_deleted", nullable = false)
    var isDeleted: Boolean = false
        protected set

    @Column(name = "created_id", nullable = false, updatable = false)
    var createdId: Long = 0
        protected set

    @Column(name = "created_at", nullable = false, updatable = false)
    var createdAt: LocalDateTime = LocalDateTime.now()
        protected set

    @Column(name = "updated_id")
    var updatedId: Long? = null
        protected set

    @Column(name = "updated_at")
    var updatedAt: LocalDateTime? = null
        protected set

    fun delete() {
        this.isDeleted = true
    }

}

 

 

  • SampleEntity
package com.woopi.safehome.domain._sample.adapter.outbound.persistence.jpa

import com.woopi.safehome.global.`object`.BaseEntity
import jakarta.persistence.Column
import jakarta.persistence.Entity
import jakarta.persistence.Table

@Entity
@Table(name = "samples")
class SampleEntity(

    @Column(name = "name")
    var name: String,

    @Column(name = "code")
    var code: String,

    @Column(name = "description")
    var description: String? = null,

    @Column(name = "order_no")
    var orderNo: Int = 0,

): BaseEntity()

 

 

  • SampleDetailEntity
package com.woopi.safehome.domain._sample.adapter.outbound.persistence.jpa

import com.woopi.safehome.global.`object`.BaseEntity
import jakarta.persistence.*

@Entity
@Table(name = "sample_details")
class SampleDetailEntity(

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "sample_id", nullable = false)
    var sample: SampleEntity,

    @Column(name = "detail_value")
    var detailValue: String? = null,

): BaseEntity()