@Getter
@NoArgsConstructor
@Entity
public class Post extends BaseTimeEntity {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
@Column(length = 500, nullable = false)
private String title;
@Column(columnDefinition = "text", nullable = false)
private String content;
@Column(nullable = false)
private String author;
@Enumerated(EnumType.STRING)
private TagType category;
@Builder
public Post(String title, String content, String author, TagType category) {
this.title = title;
this.content = content;
this.author = author;
this.category = category;
}
public void update(String title, String content){
this.title = title;
this.content = content;
}
}
@Getter
@NoArgsConstructor
@Entity
public class Post extends BaseTimeEntity {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Long postId;
@Column(length = 500, nullable = false)
private String title;
@Column(columnDefinition = "text", nullable = false)
private String content;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name= "user_id", nullable = false)
private User user;
@Enumerated(EnumType.STRING)
private TagType category;
@Builder
public Post(String title, String content, User user, TagType category) {
this.title = title;
this.content = content;
this.user= user;
this.category = category;
}
public void update(String title, String content){
this.title = title;
this.content = content;
}
}
id
를 postId
로 변경하였다.author
필드를 user
로 변경하였다. 작성자와 사용자 개념을 명확히 통합하고, 모든 사용자 관련 정보는 User
애그리거트에서 관리하도록 하기 위함이다.Post
엔티티에서 User
엔티티를 외래 키로 참조하도록 변경하였다.@ManyToOne(fetch = FetchType.LAZY)
는 여러 개의 Post
가 하나의 User
에 속하므로, Post
입장에서 User
와는 다대일(Many-to-One) 관계를 나타낸다.Post 애그리거트가 User 애그리거트를 직접 참조하면 결합도가 높아질 수 있다.
그럼에도 불구하고, 데이터베이스의 외래 키 관계를 객체 지향적으로 표현하기 위해 객체 참조 방식을 사용한다.
만약 private Long userId;
로만 관리하게 되면 post.getUser().getName()
처럼 연관된 객체의 정보를 자연스럽게 조회할 수 없고,
매번 userRepository.findById(post.getUserId())
와 같은 번거로운 조회 코드가 필요하게 된다.
또한 Post는 User를 단순히 조회만 할 뿐, User의 내부 상태를 변경하거나 로직에 깊게 의존하지 않으므로 User 애그리거트의 일관성을 해치지 않는다.
JPA의 지연 로딩(FetchType.LAZY) 전략을 활용하면, Post를 조회할 때 User의 실제 데이터를 불러오지 않고 프록시 객체만 로드하며,
이후 User의 필드에 접근할 때 실제로 쿼리를 날려 필요한 시점에만 User를 로딩할 수 있다.
PostService
save 메서드
수정 전 @Transactional
public Long save(PostCreateRequestDto requestDto, SessionUser sessionUser){
requestDto.setUserName(sessionUser.getName());
if(requestDto.getUserName()==null){
throw new IllegalArgumentException("작성자가 누락되었습니다.");
}
return postsRepository.save(requestDto.toEntity()).getId();
}