Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Step2] 연관 관계 매핑 #58

Merged
merged 6 commits into from
Jun 1, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
51 changes: 35 additions & 16 deletions src/main/java/qna/domain/Answer.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,45 @@

import java.util.Objects;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.ForeignKey;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;

import org.springframework.lang.NonNull;

import qna.NotFoundException;
import qna.UnAuthorizedException;

@Entity
public class Answer extends BaseEntity {

public static final Answer NONE = new Answer();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

테스트를 위한 코드를 도메인에 추가하는 것은 되도록 지양하는게 좋겠네요.
아래 피드백을 참고해주세요! #58 (comment)

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long writerId;
private Long questionId;

@JoinColumn(name = "writer_id",
referencedColumnName = "ID",
foreignKey = @ForeignKey(name = "fk_answer_writer"))
@ManyToOne
private User writer;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

연관관계 설정 잘해주셨네요 👍

기본 PK값으로 될텐데 referencedColumnName을 따로 설정하신 이유가 있으신가요?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

조금더 명시적이면 좋겠다라고 판단해서 작성했습니다만, 혹시 잘못된걸까요!?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

referencedColumnName 이 정의되어 있어 혹시 다른 컬럼을 지정하셨나 했습니다.
설정해보는 것도 좋다고 생각합니다 😄

그리고 보통 아래와 같은 형태로 작성을 합니다.

@ManyToOne
@JoinColumn(name = ... )

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

답글 주셨군요 ㅎㅎ 감사합니다. referencedColumnName 이라는게 있어서 사용해본 거라 제거하도록 하겠습니다 : )


@JoinColumn(name = "question_id",
referencedColumnName = "ID",
foreignKey = @ForeignKey(name = "fk_answer_to_question"))
@ManyToOne
private Question question;
@Lob
private String contents;

@NonNull
@Column(nullable = false)
private boolean deleted = false;

public Answer(User writer, Question question, String contents) {
Expand All @@ -39,19 +58,19 @@ public Answer(Long id, User writer, Question question, String contents) {
throw new NotFoundException();
}

this.writerId = writer.getId();
this.questionId = question.getId();
this.writer = writer;
this.question = question;
this.contents = contents;
}
// for jpa
protected Answer() {}

public boolean isOwner(User writer) {
return this.writerId.equals(writer.getId());
return this.writer.equals(writer);
}

public void toQuestion(Question question) {
this.questionId = question.getId();
this.question = question;
}

public Long getId() {
Expand All @@ -62,20 +81,20 @@ public void setId(Long id) {
this.id = id;
}

public Long getWriterId() {
return writerId;
public User getWriter() {
return writer;
}

public void setWriterId(Long writerId) {
this.writerId = writerId;
public void setWriter(User writerId) {
this.writer = writerId;
}
LenKIM marked this conversation as resolved.
Show resolved Hide resolved

public Long getQuestionId() {
return questionId;
public Question getQuestion() {
return question;
}

public void setQuestionId(Long questionId) {
this.questionId = questionId;
public void setQuestion(Question question) {
this.question = question;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

객체의 상태 값을 외부에서 변경할 수 있도록 열어두기 때문에 불필요한 setter()는 정리하는게 좋겠네요.

setDeleted()delete() 라는 네이밍으로 변경해보면 어떨까요?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

맞습니다..! 불필요한 메소드는 노출하지 않은게 정답이라고 생각합니다. 코드 수정하겠습니다 ㅎㅎ


public String getContents() {
Expand All @@ -98,8 +117,8 @@ public void setDeleted(boolean deleted) {
public String toString() {
return "Answer{" +
"id=" + id +
", writerId=" + writerId +
", questionId=" + questionId +
", writerId=" + writer +
", questionId=" + question +
", contents='" + contents + '\'' +
", deleted=" + deleted +
'}';
Expand Down
1 change: 1 addition & 0 deletions src/main/java/qna/domain/BaseEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public class BaseEntity {
@Column(nullable = false)
@CreatedDate
private LocalDateTime createAt;

@LastModifiedDate
private LocalDateTime updateAt;

Expand Down
24 changes: 17 additions & 7 deletions src/main/java/qna/domain/DeleteHistory.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,40 @@
import java.time.LocalDateTime;
import java.util.Objects;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.ForeignKey;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

@Entity
public class DeleteHistory {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Enumerated(value = EnumType.STRING)
private ContentType contentType;

private Long contentId;
private Long deletedById;

@JoinColumn(name = "deleted_by_id",
referencedColumnName = "ID",
foreignKey = @ForeignKey(name = "fk_delete_history_to_user"))
@ManyToOne
private User deletedBy;

private LocalDateTime createDate = LocalDateTime.now();

public DeleteHistory(ContentType contentType, Long contentId, Long deletedById, LocalDateTime createDate) {
public DeleteHistory(ContentType contentType, Long contentId, User deletedBy, LocalDateTime createDate) {
this.contentType = contentType;
this.contentId = contentId;
this.deletedById = deletedById;
this.deletedBy = deletedBy;
this.createDate = createDate;
}
// for jpa
Expand All @@ -40,12 +50,12 @@ public boolean equals(Object o) {
return Objects.equals(id, that.id) &&
contentType == that.contentType &&
Objects.equals(contentId, that.contentId) &&
Objects.equals(deletedById, that.deletedById);
Objects.equals(deletedBy, that.deletedBy);
}

@Override
public int hashCode() {
return Objects.hash(id, contentType, contentId, deletedById);
return Objects.hash(id, contentType, contentId, deletedBy);
}

@Override
Expand All @@ -54,7 +64,7 @@ public String toString() {
"id=" + id +
", contentType=" + contentType +
", contentId=" + contentId +
", deletedById=" + deletedById +
", deletedById=" + deletedBy +
", createDate=" + createDate +
'}';
}
Expand Down
44 changes: 31 additions & 13 deletions src/main/java/qna/domain/Question.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,39 @@

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.ForeignKey;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;

import org.springframework.lang.NonNull;

@Entity
public class Question extends BaseEntity {

public static final Question NONE = new Question();
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(length = 100, nullable = false)
private String title;

@Lob
private String contents;
private Long writerId;

@ManyToOne
@JoinColumn(name = "writer_id",
referencedColumnName = "ID",
foreignKey = @ForeignKey(name = "fk_question_writer")
)
private User writer;

@NonNull
@Column(nullable = false)
private boolean deleted = false;

public Question(String title, String contents) {
Expand All @@ -32,12 +50,12 @@ public Question(Long id, String title, String contents) {
protected Question() { }

public Question writeBy(User writer) {
this.writerId = writer.getId();
this.writer = writer;
return this;
}

public boolean isOwner(User writer) {
return this.writerId.equals(writer.getId());
return this.writer.equals(writer);
}

public void addAnswer(Answer answer) {
Expand Down Expand Up @@ -68,12 +86,12 @@ public void setContents(String contents) {
this.contents = contents;
}

public Long getWriterId() {
return writerId;
public User getWriter() {
return writer;
}

public void setWriterId(Long writerId) {
this.writerId = writerId;
public void setWriter(User writer) {
this.writer = writer;
}

public boolean isDeleted() {
Expand All @@ -87,11 +105,11 @@ public void setDeleted(boolean deleted) {
@Override
public String toString() {
return "Question{" +
"id=" + id +
", title='" + title + '\'' +
", contents='" + contents + '\'' +
", writerId=" + writerId +
", deleted=" + deleted +
'}';
"id=" + id +
", title='" + title + '\'' +
", contents='" + contents + '\'' +
", writerId=" + writer +
", deleted=" + deleted +
'}';
}
}
18 changes: 12 additions & 6 deletions src/main/java/qna/domain/User.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package qna.domain;

import qna.UnAuthorizedException;

import java.util.Objects;

import javax.persistence.Column;
Expand All @@ -12,21 +10,29 @@
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

import qna.UnAuthorizedException;

@Entity
@Table(uniqueConstraints = {
@UniqueConstraint(name = "UK_a3imlf41l37utmxiquukk8ajc", columnNames = {"userId"})
})
public class User extends BaseEntity{
public class User extends BaseEntity {

public static final GuestUser GUEST_USER = new GuestUser();

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(length = 20)

@Column(length = 20, nullable = false, unique = true)
private String userId;
@Column(length = 20)

@Column(length = 20, nullable = false)
private String password;
@Column(length = 20)

@Column(length = 20, nullable = false)
private String name;

@Column(length = 40)
private String email;

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/qna/service/QnaService.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ public void deleteQuestion(User loginUser, Long questionId) throws CannotDeleteE

List<DeleteHistory> deleteHistories = new ArrayList<>();
question.setDeleted(true);
deleteHistories.add(new DeleteHistory(ContentType.QUESTION, questionId, question.getWriterId(), LocalDateTime.now()));
deleteHistories.add(new DeleteHistory(ContentType.QUESTION, questionId, question.getWriter(), LocalDateTime.now()));
for (Answer answer : answers) {
answer.setDeleted(true);
deleteHistories.add(new DeleteHistory(ContentType.ANSWER, answer.getId(), answer.getWriterId(), LocalDateTime.now()));
deleteHistories.add(new DeleteHistory(ContentType.ANSWER, answer.getId(), answer.getWriter(), LocalDateTime.now()));
}
deleteHistoryService.saveAll(deleteHistories);
}
Expand Down
7 changes: 5 additions & 2 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
spring.datasource.url=jdbc:h2:~/test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.url=jdbc:h2:~/test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MODE=MySQL
spring.datasource.username=sa
spring.h2.console.enabled=true

logging.level.org.hibernate.type.descriptor.sql = trace
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.show-sql=true
spring.jpa.show-sql=true

spring.jpa.hibernate.ddl-auto=create-drop