게시판을 맡아서 개발을 하던 중 @setter 어노테이션을 통해서 게시판의 제목과 내용을 수정을 하였다.
그런데 구글링을 통해서 알아보니 @setter를 이용한 수정은 지양을 해야 한다고 한다.
지양을 해야 하는 이유는
첫 번째, 변경되지 않아야 할 값이 변경이 될 가능성이 있다.
엔티티에서는 id 즉, 엔티티를 구분하는 고유한 값이 있다.
이 값은 하나의 엔티티마다 다 다르며 엔티티마다 고유한 값을 가진다.
그런데 @setter를 사용하게 되면 id가 변경이 되는 setter메소드도 만들어지기 때문에 setter메소드를 통해서 고유한 값이 변경이 될 수도 있다.
두 번째, 객체지향에 위배되는 방법이다.
객체지향 중 갭슐화에 위배가 된다.
갭슐화는 데이터와 그 데이터를 다루는 메서드를 하나로 묶는 것을 말한다.
이를 통해서 데이터의 일관성을 유지하고 외부의 접근을 막아서 내부 구현을 숨기도록 하는 것입니다.
하지만 @setter는 모든 필드에 대해서 외부에서 변경이 가능하기 때문에 위배가 된다.
이러한 두 가지 이유로 @setter로 수정을 구현했던 부분을 개선하고자 한다.
package com.github.riset_backend.writeBoard.board.entity;
import com.github.riset_backend.login.employee.entity.Employee;
import com.github.riset_backend.writeBoard.board.dto.BoardRequestDto;
import com.github.riset_backend.writeBoard.boardFile.entity.BoardFile;
import com.github.riset_backend.writeBoard.reply.entity.Reply;
import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.DynamicUpdate;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "board")
@EntityListeners(AuditingEntityListener.class)
@DynamicUpdate
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "board_no")
private Long boardNo;
@ManyToOne
@JoinColumn(name = "employee_no")
private Employee employee;
@Column(name = "title")
private String title;
@Column(name = "content")
private String content;
@CreatedDate
@Column(updatable = false)
private LocalDateTime createAt;
@Column(name = "deleted")
private String deleted;
@OneToMany(mappedBy = "board", fetch = FetchType.LAZY)
private List<BoardFile> boardFiles;
@OneToMany(mappedBy = "board", fetch = FetchType.LAZY)
private List<Reply> replies;
public Board(Long boardNo) {
this.boardNo = boardNo;
}
}
if(boardRequestDto.getContent() != null) {
board.setContent(boardRequestDto.getContent());
}
if(boardRequestDto.getTitle() != null) {
board.setTitle(boardRequestDto.getTitle());
}
@Setter라는 어노테이션을 엔티티에 붙혀주고 있다.
그리고 service에서 setter 메소드를 통해서 수정을 해주고 있다.
이 방법으로도 수정이 가능하지만 외부에서 접근이 너무 쉽고 객체지향적이지 못한 부분이다.
package com.github.riset_backend.writeBoard.board.entity;
import com.github.riset_backend.login.employee.entity.Employee;
import com.github.riset_backend.writeBoard.board.dto.BoardRequestDto;
import com.github.riset_backend.writeBoard.boardFile.entity.BoardFile;
import com.github.riset_backend.writeBoard.reply.entity.Reply;
import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.DynamicUpdate;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "board")
@EntityListeners(AuditingEntityListener.class)
@DynamicUpdate
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "board_no")
private Long boardNo;
@ManyToOne
@JoinColumn(name = "employee_no")
private Employee employee;
@Column(name = "title")
private String title;
@Column(name = "content")
private String content;
@CreatedDate
@Column(updatable = false)
private LocalDateTime createAt;
@Column(name = "deleted")
private String deleted;
@OneToMany(mappedBy = "board", fetch = FetchType.LAZY)
private List<BoardFile> boardFiles;
@OneToMany(mappedBy = "board", fetch = FetchType.LAZY)
private List<Reply> replies;
public Board(Long boardNo) {
this.boardNo = boardNo;
}
public Board updateBoard(BoardRequestDto boardRequestDto) {
if (boardRequestDto.getTitle() != null) {
this.title = boardRequestDto.getTitle();
}
if (boardRequestDto.getContent() != null) {
this.content = boardRequestDto.getContent();
}
return this;
}
}
엔티티 안에 수정 메소그를 만들어서 이 메소드를 통해서 수정을 해준다.
이 방법을 사용하면 모든 필드에 대해서 수정이 가능한 메소드가 생기는 것이 아니라 필요한 필드에 대해서만 수정이 가능하다.
따라서 첫 번째인 고유한 값이 변경이 되는 우려가 없어지고 객체지향을 위배하는 일이 없어진다.