2021-03-17-TIL

2021-03-17 10:40:23.822 ERROR 3172 --- [nio-8080-exec-2] c.codesquad.qna.service.QuestionService  : Question : Question{id=0, writer='', title='Hi, Dong!', contents='sdffdfd', createdDateTime=2021-03-17T10:40:23.822268}
Hibernate: 
    insert 
    into
        question
        (id, contents, created_date_time, title, writer) 
    values
        (null, ?, ?, ?, ?)

아래의 물음표는 Hibernate가 미리 쿼리를 저렇게 컴파일 해놓고, 나머지 값들을 넣어서 실행하는 것이라서 저 단계에서 에러가 발생한다. Question을 로그로 찍어보니 값이 안 넘어가는 것이 아니었다!

Type Exception Report

Message Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint ["PUBLIC.UK_JY4GREMN0GU663AD6XE83SB57_INDEX_E ON PUBLIC.QUESTION(WRITER) VALUES 1"; SQL statement:

Description The server encountered an unexpected condition that prevented it from fulfilling the request.

Exception

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint ["PUBLIC.UK_JY4GREMN0GU663AD6XE83SB57_INDEX_E ON PUBLIC.QUESTION(WRITER) VALUES 1"; SQL statement:
insert into question (id, contents, created_date_time, title, writer) values (null, ?, ?, ?, ?) [23505-200]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
...

그런데 여기서 주의할 점은 칼럼 1번이 id가 아니라는 점이다. 자세히 읽어보면 WRITER이 VALUES 1번이고 여기에서 제약조건 위반이 발생했다고 나온다.

@Column(nullable = false, length = 32, unique = true)
private String writer;

원인을 제대로 찾지 못하면 결국 애꿎은 코드만 파헤쳐지고 부서진다. 정확한 원인을 찾기 위해서는 로그를 찍어보고 에러메시지를 꼼꼼히 읽어보는 것이 중요하다.


미션 3: 로그인 구현

안녕하세요, 코드스쿼드 백엔드 반의 August입니다. 항상 좋은 리뷰 감사합니다! 이번 과제는 주어진 필수 요구사항인 로그인, 로그인 상태에 따른 네비게이션 바 변경, 로그아웃, 계정 정보 수정, 질문 생성/수정/삭제 까지 구현했습니다.

선택 사항인 User와 Question 연결은 구현하지 않았고, 질문을 수정하거나 삭제할 때 현재 세션의 userId와 질문 글의 writer를 매칭하여 일치할 때만 수행하는 방식으로 작성하였습니다.

  • 서버 주소 : https://august-qna.herokuapp.com/

  • 미리 생성된 계정

    아이디 패스워드
    august 1234
    hello 1212
    legend password

구현 내용

  • QuestionController
    • updateForm - 세션을 가져오고 변경할 질문을 가져와서 작성자와 세션 유저의 userId가 일치할 때만 /qna/updateForm을 띄워줍니다.
    • update - 세션을 가져오고 변경할 질문을 가져와서 작성자와 세션 유저의 userId가 일치할 때만 QuestionService::update를 호출합니다.
    • delete - 세션을 가져오고 작성자와 세션 유저의 userId가 일치할 때만 QuestionService::delete를 호출하여 삭제합니다.
  • QuestionService
    • update - 기존의 Question과 새로운 Question을 받아서 update하고, QuestionRepository의 save를 호출합니다. 여기에서 questionRepository.save(question)이 없어도 기존에 추가된 레코드에 대해서 수정이 된다고 하는데, 저는 그렇게 동작하지 않아서 그냥 두었습니다.
    • delete - 단순히 QuestionRepository의 delete를 호출합니다.

Q) 500에러가 발생했을 때 핸들링해서 커스텀 에러페이지를 띄워주도록 하는 방법?

Q) DTO를 적용하는 방법?

TIP: 검색 잘 하는 법?


[아이작]

  • indexOf가 내부적으로 반복문을 수행할 텐데 반복문을 하나로 줄일 수 있을 것 같다.
  • updateUserInfo …?
  • HomeController에 @Controller 애노테이션을 빼고 하면 에러난다.

[August]

  • Logger 사용할 것 -> System.out.println이 남아있던데 Logger 사용으로 완전히 전환하면 좋을 것 같습니다!

[coco]

[pyro]

  • 만약에 profile을 index로 지정하고 싶다면? -> profile.html을 index.html로 변경한다? -> HomeController의 맵핑을 코드 한 줄로 변경할 수 있다. index.html이 뭔지 모르는 사람은 의미도 모른채 파일을 열어봐야한다. 하지만 qna/list.html로 관리하면 좀 더 의미도 명확하고, 유지보수에 용이하다.

  • HomeController 작성한 이유? ->

  • Model에 add해주는 것 만으로도 어떻게 저기로 넘어가는가?

    https://terasolunaorg.github.io/guideline/1.0.1.RELEASE/en/Overview/SpringMVCOverview.html#:~:text=Spring%20Reference%20Document.,the%20development%20of%20web%20applications.