@JoinColumn 을 선언하는 필드가 주인.mappedBy = "주인측필드명" 으로 매핑. DB 변경은 직접 못 하고 읽기 전용 뷰 성격.@Entity : 클래스 ↔ 테이블 매핑
@Id : PK 지정
@Table(name=...) : 테이블명 지정
@GeneratedValue(strategy=GenerationType.IDENTITY)
: MySQL의 AUTO_INCREMENT
@Column(...) : 컬럼 상세 옵션
- nullable / unique / name / length / insertable / updatable
주의:
@GeneratedValue철자 정확히(오타@GeneratedValued금지)
Board 테이블에 있으므로, Board 쪽 필드(Category를 참조하는 기존 필드명)가 주인입니다.// BoardEntity.java
// (기존에 CategoryEntity를 참조하는 필드가 있다고 가정)
// 예) private CategoryEntity category; // ← "category" 라는 이름이 아니어도 됨. 기존 이름 유지!
// [추가/보완] 외래키를 가진 주인쪽 어노테이션만 부여
@ManyToOne(fetch = FetchType.LAZY) // 지연로딩 권장
@JoinColumn(name = "category_id") // FK 컬럼명 (DB에 맞게 유지/수정)
private CategoryEntity [기존_카테고리_참조_필드명];
// CategoryEntity.java
// (이미 Board 리스트를 보유한 컬렉션 필드 존재 가정;)
// 예) private List<BoardEntity> boards = new ArrayList<>();
// [추가/보완] 비주인(inverse) 쪽 설정
@OneToMany(mappedBy = "[Board에서_Category를_가리키는_필드명]",
cascade = CascadeType.ALL,
orphanRemoval = true)
private List<BoardEntity> [기존_보드_컬렉션_필드명];
mappedBy값은 BoardEntity에서 Category를 참조하는 필드의 정확한 이름이어야 합니다.
예: Board 쪽 필드명이categoryRef라면mappedBy = "categoryRef".
Reply 테이블에 있으므로, Reply 쪽 필드(Board를 참조하는 기존 필드명)가 주인입니다.// ReplyEntity.java
// (BoardEntity를 참조하는 기존 필드가 있다고 가정)
// 예) private BoardEntity board;
// [추가/보완] 주인쪽 어노테이션
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "board_id")
private BoardEntity [기존_보드_참조_필드명];
// BoardEntity.java
// (Reply 컬렉션 보유한 기존 필드 가정)
// 예) private List<ReplyEntity> replies = new ArrayList<>();
// [추가/보완] 비주인쪽 설정
@OneToMany(mappedBy = "[Reply에서_Board를_가리키는_필드명]",
cascade = CascadeType.ALL,
orphanRemoval = true)
private List<ReplyEntity> [기존_리플_컬렉션_필드명];
mappedBy값은 ReplyEntity에서 Board를 참조하는 필드의 정확한 이름이어야 합니다.
// BoardEntity.java
public void addReply(ReplyEntity reply) {
this.[기존_리플_컬렉션_필드명].add(reply);
reply.set[Board_참조_필드의_Setter](this); // 예: reply.setBoard(this);
}
public void removeReply(ReplyEntity reply) {
this.[기존_리플_컬렉션_필드명].remove(reply);
reply.set[Board_참조_필드의_Setter](null);
}
// CategoryEntity.java
public void addBoard(BoardEntity board) {
this.[기존_보드_컬렉션_필드명].add(board);
board.set[Category_참조_필드의_Setter](this); // 예: board.setCategory(this);
}
public void removeBoard(BoardEntity board) {
this.[기존_보드_컬렉션_필드명].remove(board);
board.set[Category_참조_필드의_Setter](null);
}
@ManyToOne(fetch = FetchType.LAZY) 명시 권장.@OneToMany 는 기본이 LAZY. @EntityGraph 사용.// 예시: Board와 replies를 한 번에
//@EntityGraph(attributePaths = "[기존_리플_컬렉션_필드명]")
//Optional<BoardEntity> findById(Long id);
cascade = CascadeType.ALL : 부모가 삭제/수정되면 자식도 함께 삭제/수정 (권장)
cascade = CascadeType.PERSIST : 부모가 저장되면 자식도 저장
cascade = CascadeType.MERGE : 부모가 수정되면 자식도 수정
cascade = CascadeType.REMOVE : 부모가 삭제되면 자식도 삭제
cascade = CascadeType.REFRESH : 부모가 재호출(갱신)되면 자식도 재호출(갱신)
cascade = CascadeType.DETACH : 부모가 영속 해제되면 자식도 영속 해제