Skip to the content.

PersistencePort (Command Port) — CQRS Command 추상화

PersistencePort는 Domain Aggregate를 영속화하는 쓰기 전용 Port입니다.

persist() 메서드 하나로 INSERT/UPDATE를 통합 처리합니다.


1) 핵심 역할


2) 핵심 원칙

원칙 1: persist() 메서드 하나만

원칙 2: Domain Aggregate 파라미터

원칙 3: Value Object 반환

원칙 4: 조회 메서드 금지


3) 템플릿 코드

package com.ryuqq.application.{bc}.port.out.command;

import com.ryuqq.domain.{bc}.{Bc};
import com.ryuqq.domain.{bc}.{Bc}Id;

/**
 * {Bc} Persistence Port (Command)
 *
 * <p>Domain Aggregate를 영속화하는 쓰기 전용 Port</p>
 *
 * @author development-team
 * @since 1.0.0
 */
public interface {Bc}PersistencePort {

    /**
     * {Bc} 저장 (신규 생성 또는 수정)
     *
     * <p>신규 생성 (ID 없음) → INSERT</p>
     * <p>기존 수정 (ID 있음) → UPDATE (JPA 더티체킹)</p>
     *
     * @param {bc} 저장할 {Bc} (Domain Aggregate)
     * @return 저장된 {Bc}의 ID (Value Object)
     */
    {Bc}Id persist({Bc} {bc});
}

4) 실전 예시 (Order)

package com.ryuqq.application.order.port.out.command;

import com.ryuqq.domain.order.Order;
import com.ryuqq.domain.order.OrderId;

/**
 * Order Persistence Port (Command)
 *
 * <p>Order Aggregate를 영속화하는 쓰기 전용 Port</p>
 *
 * @author development-team
 * @since 1.0.0
 */
public interface OrderPersistencePort {

    /**
     * Order 저장 (신규 생성 또는 수정)
     *
     * <p>신규 생성 (ID 없음) → INSERT</p>
     * <p>기존 수정 (ID 있음) → UPDATE (JPA 더티체킹)</p>
     *
     * @param order 저장할 Order (Domain Aggregate)
     * @return 저장된 Order의 ID
     */
    OrderId persist(Order order);
}

5) Do / Don’t

❌ Bad Examples

// ❌ save(), update(), delete() 메서드
public interface OrderPersistencePort {
    void save(Order order);    // 금지!
    void update(Order order);  // 금지!
    void delete(OrderId id);   // 금지!
}

// ❌ 조회 메서드 포함
public interface OrderPersistencePort {
    OrderId persist(Order order);
    Optional<Order> findById(OrderId id);  // 금지! QueryPort로 분리
}

// ❌ 원시 타입 반환
public interface OrderPersistencePort {
    Long persist(Order order);  // 금지! OrderId 반환
}

// ❌ DTO 파라미터
public interface OrderPersistencePort {
    OrderId persist(OrderDto dto);  // 금지! Domain Aggregate 사용
}

// ❌ Entity 파라미터
public interface OrderPersistencePort {
    OrderId persist(OrderJpaEntity entity);  // 금지! Domain Aggregate 사용
}

✅ Good Examples

// ✅ persist() 메서드 하나만
public interface OrderPersistencePort {
    OrderId persist(Order order);
}

// ✅ Domain Aggregate 파라미터, Value Object 반환
public interface OrderPersistencePort {
    OrderId persist(Order order);  // Order (Domain), OrderId (VO)
}

// ✅ 패키지 위치
// application/{bc}/port/out/command/{Bc}PersistencePort.java
package com.ryuqq.application.order.port.out.command;

public interface OrderPersistencePort {
    OrderId persist(Order order);
}

6) 체크리스트

PersistencePort 작성 시:


📖 관련 문서


작성자: Development Team 최종 수정일: 2025-11-12 버전: 1.0.0