Skip to content

JPA Create And Update Value

정명주(myeongju.jung) edited this page Aug 5, 2018 · 6 revisions

Create And Update 비교

상속

  • 도메인에서 핵심 관심사를 관통하는 용도로 상속이라는 귀중한 기회를 사용해야한다고 봄.
  • 하지만 팀의 합의가 있다면 구현 편의를 위해서 상속을 사용하는 것도 하나의 방법임.
    • 개인적으로는 권장하지 않음
    • 하지만 대중적으로 가장 많이 쓰이고 있고 개발 시 편함
@Getter
@ToString
@EqualsAndHashCode
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
class BaseEntity {
    @CreatedBy
    private Long createdUserId
    @CreatedDate
    private Date createdAt;
    @LastModifiedBy
    private Long lastModifiedUserId
    @LastModifiedDate
    private Date lastModified;
}
@Configuration
@EnableJpaAuditing // 이 설정이 있어야지 위 어노테이션이 정상작동
class JpaConfig {
    @Bean
    public AuditorAware<AuditableUser> auditorProvider() {
        return new MyAuditorAware(); // 사용자 조회 용
    }
}

CreateAndUpdate

  • 등록과 수정정보과 통합된 형태의 값객체
@Embeddable
@Getter
@ToString
@EqualsAndHashCode
@AllArgsConstructor
public class CreateAndUpdate {
    public static final String CN_CREATE_USER_NO = "CREATE_USER_NO";
    public static final String CN_CREATED_AT = "CREATED_AT";
    public static final String CN_UPDATE_USER_NO = "UPDATE_USER_NO";
    public static final String CN_UPDATED_AT = "UPDATED_AT";

    public static final String DB_CURRENT_TIMESTAMP = "CURRENT_TIMESTAMP";
    /**
     * 등록 회원번호
     */
    @Column(name = CN_CREATE_USER_NO, nullable = false, updatable = false)
    private final Long createUserNo;
    /**
     * 등록일시
     */
    @ColumnDefault(DB_CURRENT_TIMESTAMP)
    @Generated(GenerationTime.INSERT)
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = CN_CREATED_AT, nullable = false, insertable = false, updatable = false)
    private final Date createdAt;
    /**
     * 수정 회원번호
     */
    @Column(name = CN_UPDATE_USER_NO, insertable = false)
    private Long updateUserNo;
    /**
     * 수정일시
     */
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = CN_UPDATED_AT, insertable = false)
    private Date updatedAt;

    protected CreateAndUpdate() {
        this.createUserNo = null;
        this.createdAt = null;
    }
    private CreateAndUpdate(Long createUserNo) {
        this.createUserNo = createUserNo;
        this.createdAt = null;
        this.updateUserNo = null;
        this.updatedAt = null;
    }

    public static CreateAndUpdate create(@NonNull Long createUserNo) {
        return new CreateAndUpdate(createUserNo);
    }

    public void update(@NonNull Long updateUserNo) {
        this.updateUserNo = updateUserNo;
        this.updatedAt = new Date();
    }

    public void checkPreInsert() {
        if (createUserNo == null) {
            throw new IllegalStateException("'createUserNo' not exist when create");
        }
    }

    public void checkPreUpdate() {
        if (createUserNo == null) {
            throw new IllegalStateException("'createUserNo' not exist when update");
        }
        if (updateUserNo == null) {
            throw new IllegalStateException("'updateUserNo' not exist when update");
        }
    }
}

Register, Modify

  • 등록과 수정정보과 분리된 형태의 값객체

Storeable

public interface Storeable {
    String getMemberId();
    ZonedDateTime getTs();
}

Register

@Value
@Embeddable
@AllArgsConstructor
public class Register implements Storeable, Serializable {
    private static final long serialVersionUID = 6901279822511498217L;
    @Column(name = "register_member_id", length = 100, nullable = false, updatable = false)
    private final String memberId;

    @Generated(GenerationTime.INSERT)
    @ColumnDefault(DB_CURRENT_TIMESTAMP)
    @Column(name = "register_ts", nullable = false, insertable = false, updatable = false)
    private final ZonedDateTime ts;

    // for JPA
    protected Register() {
        this.memberId = null;
        this.ts = null;
    }

    public static Register create(String registerMemberId) {
        if (StringUtils.isBlank(registerMemberId)) {
            throw new IllegalArgumentException("'registerMemberId' is blank");
        }
        return new Register(registerMemberId, ZonedDateTime.now());
    }

    public boolean isEmpty() {
        return memberId == null && ts == null;
    }
}

Modify

@Value
@Embeddable
@AllArgsConstructor
public class Modify implements Storeable, Serializable {
    public static final String DB_CURRENT_TIMESTAMP = "CURRENT_TIMESTAMP";
    private static final long serialVersionUID = -1206032844696773181L;

    @Column(name = "modify_member_id", length = 100, nullable = false)
    private String memberId;

    //    @Generated(GenerationTime.INSERT) // 이 부분은 고민 중
    @ColumnDefault(DB_CURRENT_TIMESTAMP)
    @Column(name = "modify_ts", insertable = false, nullable = false)
    private ZonedDateTime ts;

    // for JPA
    protected Modify() {
        this.memberId = null;
        this.ts = null;
    }

    public static Modify create(String modifyMemberId) {
        if (StringUtils.isBlank(modifyMemberId)) {
            throw new IllegalArgumentException("'modifyMemberId' is blank");
        }
        return new Modify(modifyMemberId, ZonedDateTime.now());
    }
}
Clone this wiki locally