Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/main/java/codesquad/QnaApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@EnableJpaAuditing
@SpringBootApplication
public class QnaApplication {
public static void main(String[] args) {
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/codesquad/domain/BaseTimeEntity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package codesquad.domain;

import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.time.LocalDateTime;

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class BaseTimeEntity {

@CreatedDate
private LocalDateTime createdDate;

public LocalDateTime getCreatedDate() {
return createdDate;
}
}
28 changes: 28 additions & 0 deletions src/main/java/codesquad/domain/Result.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package codesquad.domain;

public class Result<T> {

private T data;
private String errorMessage;

private Result(T data, String errorMessage) {
this.data = data;
this.errorMessage = errorMessage;
}

public static <T> Result<T> ok(T data) {
return new Result<>(data, null);
}

public static <T> Result<T> fail(String errorMessage) {
return new Result<>(null, errorMessage);
}

public T getData() {
return data;
}

public String getErrorMessage() {
return errorMessage;
}
}
24 changes: 18 additions & 6 deletions src/main/java/codesquad/domain/answer/Answer.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package codesquad.domain.answer;

import codesquad.domain.BaseTimeEntity;
import codesquad.domain.question.Question;
import codesquad.domain.user.User;

import javax.persistence.*;

@Entity
public class Answer {
public class Answer extends BaseTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Expand All @@ -15,14 +16,25 @@ public class Answer {
@JoinColumn(foreignKey = @ForeignKey(name = "fk_answer_writer"))
private User writer;

@ManyToOne
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(foreignKey = @ForeignKey(name = "fk_answer_to_question"))
private Question question;

@Column(columnDefinition = "TEXT", length = 300, nullable = false)
private String contents;

private Boolean isDeleted = false;
@Column(columnDefinition = "boolean default false")
private boolean deleted = false;

public Answer() {

}

public Answer(User writer, Question question, String contents) {
this.writer = writer;
this.question = question;
this.contents = contents;
}

public Long getId() {
return id;
Expand Down Expand Up @@ -56,15 +68,15 @@ public void setContents(String contents) {
this.contents = contents;
}

public Boolean getDeleted() {
return isDeleted;
public boolean isDeleted() {
return deleted;
}

public boolean isSameWriter(User user) {
return this.writer.isSameUser(user);
}

public void delete() {
isDeleted = true;
deleted = true;
}
}
6 changes: 6 additions & 0 deletions src/main/java/codesquad/domain/answer/AnswerRepository.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package codesquad.domain.answer;

import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface AnswerRepository extends JpaRepository<Answer, Long> {

@EntityGraph(attributePaths = {"question"})
Optional<Answer> findQuestionFetchJoinById(Long id);
}
19 changes: 15 additions & 4 deletions src/main/java/codesquad/domain/question/Question.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package codesquad.domain.question;

import codesquad.domain.BaseTimeEntity;
import codesquad.domain.answer.Answer;
import codesquad.domain.user.User;
import com.fasterxml.jackson.annotation.JsonIgnore;

import javax.persistence.*;
import java.util.List;

@Entity
public class Question {
public class Question extends BaseTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long index;
Expand All @@ -23,11 +25,13 @@ public class Question {
private String contents;

@OneToMany(mappedBy = "question")
@JsonIgnore
private List<Answer> answers;

private Integer countOfAnswer = 0;

private Boolean isDeleted = false;
@Column(columnDefinition = "boolean default false")
private boolean deleted = false;

public Long getIndex() {
return index;
Expand Down Expand Up @@ -99,11 +103,18 @@ public void deleteAnswer() {
}

public void delete() {
isDeleted = true;
deleted = true;
}

public boolean isDeleted() {
return deleted;
}

public boolean canDelete() {
if (countOfAnswer.equals(0)) {
boolean isAnswerStatusAllTrue = answers.stream()
.allMatch(answer -> answer.isDeleted() == true);

if (countOfAnswer.equals(0) || isAnswerStatusAllTrue) {
return true;
}
return false;
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/codesquad/domain/user/User.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package codesquad.domain.user;

import codesquad.domain.BaseTimeEntity;

import javax.persistence.*;

@Entity
public class User {
public class User extends BaseTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Expand Down
65 changes: 65 additions & 0 deletions src/main/java/codesquad/web/ApiAnswerController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package codesquad.web;

import codesquad.domain.Result;
import codesquad.domain.answer.Answer;
import codesquad.domain.answer.AnswerRepository;
import codesquad.domain.question.Question;
import codesquad.domain.question.QuestionRepository;
import codesquad.domain.user.User;
import codesquad.util.HttpSessionUtil;
import codesquad.web.dto.AnswerSaveRequestDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.util.NoSuchElementException;

@RestController
@RequestMapping("/api/questions/{index}/answers")
public class ApiAnswerController {

@Autowired
private QuestionRepository questionRepository;

@Autowired
private AnswerRepository answerRepository;

@PostMapping("")
public Answer create(@PathVariable Long index, @RequestBody AnswerSaveRequestDto answerSaveRequestDto, HttpSession httpSession) {
if(!HttpSessionUtil.isLoginUser(httpSession)) {
return null;
}

User sessionedUser = HttpSessionUtil.getUserFrom(httpSession);
Question savedQuestion = questionRepository.findById(index).orElseThrow(() -> new NoSuchElementException("게시글이 존재하지 않습니다."));
Answer answer = new Answer(sessionedUser, savedQuestion, answerSaveRequestDto.getContents());
savedQuestion.addCountOfAnswer();

return answerRepository.save(answer);
}

@DeleteMapping("/{id}")
public Result<Answer> delete(@PathVariable Long index, @PathVariable Long id, HttpSession httpSession) {
if(!HttpSessionUtil.isLoginUser(httpSession)) {
return Result.fail("세션이 만료되었습니다. 다시 로그인 해주세요.");
}

Answer savedAnswer = answerRepository.findQuestionFetchJoinById(id).orElseThrow(() -> new NoSuchElementException("답변이 존재하지 않습니다."));
User sessionedUser = HttpSessionUtil.getUserFrom(httpSession);

if (!savedAnswer.isSameWriter(sessionedUser)) {
return Result.fail("다른 사람의 게시글을 삭제할 수 없습니다.");
}

savedAnswer.delete();

answerRepository.save(savedAnswer);

Question savedQuestion = questionRepository.findById(index).orElseThrow(() -> new NoSuchElementException("게시글이 존재하지 않습니다."));
savedQuestion.deleteAnswer();

questionRepository.save(savedQuestion);

return Result.ok(savedAnswer);
}
}
2 changes: 1 addition & 1 deletion src/main/java/codesquad/web/QuestionController.java
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public String delete(@PathVariable Long index, HttpSession httpSession, Redirect
}

if (!savedQuestion.canDelete()) {
throw new IllegalStateException("질문에 다른 사용자의 답변이 존재하여 질문을 삭제할 수 없습니다.");
throw new IllegalStateException("질문을 삭제할 수 없습니다.");
}

savedQuestion.delete();
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/codesquad/web/dto/AnswerSaveRequestDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package codesquad.web.dto;

public class AnswerSaveRequestDto {

private String contents;

public String getContents() {
return contents;
}
}
6 changes: 4 additions & 2 deletions src/main/resources/data.sql
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
INSERT INTO USER (id, user_id, password, name, email) VALUES (1, 'javajigi', 'test', '자바지기', 'javajigi@slipp.net');
INSERT INTO USER (id, user_id, password, name, email) VALUES (2, 'sanjigi', 'test', '산지기', 'sanjigi@slipp.net');
INSERT INTO USER (id, created_date, user_id, password, name, email) VALUES (1, '2022-04-18 16:20:29.311', 'javajigi', 'test', '자바지기', 'javajigi@slipp.net');
INSERT INTO USER (id, created_date, user_id, password, name, email) VALUES (2, '2022-04-18 16:20:29.311', 'sanjigi', 'test', '산지기', 'sanjigi@slipp.net');

INSERT INTO QUESTION(index, created_date, contents, count_of_answer, deleted, title, writer_id) VALUES(1, '2022-04-19 16:20:29.311', '자동차 경주 게임을 수행하세요.', 0, false, '오늘의 미션은?', 1);
Loading