프로젝트 진행 중에 초기에 사용자 신고 만을 위해 구현했던 기능이, 다른 두가지 도메인에 대한 신고로 늘어나게 되었습니다. 무작정 코드를 작성하던 와중에, 코드의 중복이 심해져 엔티티 클래스에서 추상화를 통해 해결하는 방식을 택하여 구현을 하게 되었습니다.
@Entity
@Getter
@Table(name = "reports")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Report extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "reporter_id")
User reporter;
@Column(name = "reported_id")
Long reportedId;
@Column(name = "content")
String content;
사용자 신고를 위해 User 도메인과 일대다 관계를 맺어 해결
@Getter
@SuperBuilder
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public abstract class Report {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "reporter_id")
private User reporter;
@Column(name = "content")
private String content;
@CreatedDate
@Column(name = "created_at")
private LocalDateTime createdAt;
@Column(name = "updated_at")
private LocalDateTime updatedAt;
@Column(name = "deleted_at")
private LocalDateTime deletedAt;
공통된 Report(신고)의 필드를 추상화 클래스로 만들고, 이 클래스를 상속하여 만들도록 클래스를 구성하였습니다.
@SuperBuilder
: 상속 받은 클래스의 필드를 빌더 등에서 사용하지 못하는 제한을 보완하기 위해 사용했습니다. (부모 클래스와 자식 클래스에 모두 사용해야 합니다.)@MappedSuperClass
: JPA에 적용되지 않는 데이터베이스의 상속 개념을 슈퍼타입-서브타입으로 구현해 Entity 클래스로 사용하기 위해 사용했습니다.// 사용자 신고 엔터티
@Entity
@Getter
@SuperBuilder
@Table(name = "user_reports")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class UserReport extends Report {
@ManyToOne
@JoinColumn(name = "reported_id")
private User reportedUser;
public UserReport(User reportedUser) {
this.reportedUser = reportedUser;
}
}
// 댓글 신고 엔터티
@Entity
@Getter
@SuperBuilder
@Table(name = "reply_reports")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class ReplyReport extends Report {
@ManyToOne
@JoinColumn(name = "reply_id")
private Reply reply;
public ReplyReport(User reporter, Reply reply, String content) {
this.reply = reply;
}
}
이렇게 상속을 받으면, 엔터티를 추상화를 통해 구현하여, 중복된 코드를 줄이고, 코드 가독성을 높일 수 있습니다.