구현순서 (Bottom-Up: 상향식. 즉, 아래(도메인)부터 위(컨트롤러)로 )
도메인 엔티티 → DTO & Command (데이터 구조 정의) → Repository Interface → Service (비즈니스 로직) → 컨트롤러
<aside> 💡
구분 기준 (위 경우는 실행 흐름 관점)
실행 흐름 관점의 '상/하위’ → 데이터의 흐름이나 호출 순서를 기준
(사용자와 가까운 컨트롤러가 상위 / db와 가까운 도메인이 하위)
의존성 규칙 관점의 '고/저수준’ → 누가 더 중요하고, 누가 누구에게 의존해야 하는가의 기준
(비즈니스 로직을 담은 도메인이 고수준 / 서비스를 의존하는 컨트롤러가 저수준)
</aside>
@NotNull vs @Column의 nullable=false
엔티티 설계 시, 일반적으로 @Column 어노테이션을 활용
→ @Column의 nullable=false 설정으로 NOT NULL 제약조건 명시 가능 (기본값은 true)
→ 이 경우, 데이터베이스 컬럼의 속성이기에 애플리케이션 내부에서는 NULL 값이 허용됨. (데이터베이스 쿼리가 실행될 때 예외 발생)
@NOT NULL 어노테이션도 마찬가지로 DDL 상에서 해당 컬럼이 NOT NULL 제약조건을 가짐을 명시 가능
→ 차이점은 스프링(자바) 애플리케이션 내에서 예외를 잡아줌. (불필요한 쿼리 발생 X) (javax.validation.ConstraintViolationException 예외 발생)
→ 엔티티가 영속화되는 시점에 예외 발생

StringUtils.hasText: Spring 프레임워크가 제공하는 유용한 문자열 검증 유틸리티 메서드
→ 3가지 모두 검사 (성공 시, true 반환)
null이 아닌가?"")이 아닌가?" ")이 아닌가?엔티티의 데이터 삭제 (연관된 엔티티)
//3가지 케이스
this.activeDays.clear(); //연결관계 끊기 (리스트이기에 clear로 전체 삭제)
this.partyImg = null; //연결관계 끊기 (단일 객체기에 null)
this.content = request.content(); //연관된 엔티티가 아닌 그냥 필드인 경우, 값만 넣어줘도 됨
양방향 관계 설정 (연관관계 편의 메서드)
public void addActiveDay(ActiveDay day) {
//자식(PartyActiveDay)을 부모(Party) 안에서 직접 생성
PartyActiveDay partyActiveDay = PartyActiveDay.builder()
.activeDay(day)
.party(this) //**생성 시점에 바로 부모-자식 관계 설정**
.build();
this.activeDays.add(partyActiveDay); //부모에게 자식을 설정
}
public void addMember(MemberParty memberParty) {
this.memberParties.add(memberParty); //부모에게 자식을 설정
memberParty.setParty(this); //이미 만들어진 자식에게 부모를 설정
}