2021-03-22-TIL

javax.servlet.ServletException: Circular view path [error]: would dispatch back to the current handler URL [/error] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)
	at org.springframework.web.servlet.view.InternalResourceView.prepareForRendering(InternalResourceView.java:210) ~[spring-webmvc-5.3.4.jar:5.3.4]
	at ...
  • https://stackoverflow.com/questions/18813615/how-to-avoid-the-circular-view-path-exception-with-spring-mvc-test
  • https://www.baeldung.com/spring-circular-view-path-error
  • https://stackoverflow.com/questions/36697663/circular-view-path-error-spring-boot/57165885

메시지를 잘 읽어보면 그냥 /error에 대한 페이지가 없어서 저렇게 에러페이지가 뜨는 것 같다. 그래서 /templates/error/400.html을 우선 만들어주면 해당 에러는 발생하지 않고, 작성한 커스텀 에러페이지가 뜬다.

그렇다면 진짜 원인을 알기위해서 디버그 수준을 더욱 낮춘다.

logging.level.org.springframework.web=DEBUG
logging.level.com=DEBUG

그리고 다시 질문하기 버튼을 클릭했을 때 아래와 같은 에러 메시지를 확인할 수 있다.

Field error in object 'question' on field 'writer': rejected value [august]; codes [typeMismatch.question.writer,typeMismatch.writer,typeMismatch.com.codesquad.qna.domain.User,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [question.writer,writer]; arguments []; default message [writer]]; default message [Failed to convert value of type 'java.lang.String[]' to required type 'com.codesquad.qna.domain.User'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.lang.Long] for value 'august'; nested exception is java.lang.NumberFormatException: For input string: "august"]
	at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.constructAttribute(ModelAttributeMethodProcessor.java:304)
	at ...
<!--value=""-->

input 필드에 value속성으로 미리 세션유저의 userId를 가져와서 String으로 보여주는 부분이 있는데, 이 부분이 form태그 안에 같이 포함이 되어서 같이 POST 메소드로 넘어간다는 점이 문제가 되었다!

부가기능을 미리 추가하면 에러 디버깅이 더욱 힘들어진다. 핵심기능을 우선적으로 구현하고 부가기능은 이후에 구현하는 것이 빠른 구현의 방법인 것 같다.

JPA의 외래키 자동맵핑

Hibernate:

create table question (
   id bigint generated by default as identity,
    contents varchar(3000),
    created_date_time timestamp,
    title varchar(255) not null,
    writer_id bigint,
    primary key (id)
)
create table user (
   id bigint generated by default as identity,
    email varchar(64),
    name varchar(32),
    password varchar(64) not null,
    user_id varchar(32) not null,
    primary key (id)
)
alter table user 
   add constraint UK_a3imlf41l37utmxiquukk8ajc unique (user_id)

User 테이블의 user_id에 제약사항을 추가하는데, 뭔지는 모르지만 외래키 관련 제약사항인 것 같다.

alter table question 
   add constraint fk_question_writer 
   foreign key (writer_id) 
   references user

Question 테이블에서는 외래키로서 User 테이블의 writer_id를 참조하도록 설정한다.

image-20210322235535499

Question의 스키마를 확인해보니, 로그에서 나온대로 writer_id 칼럼이 추가된 것을 확인할 수 있다. 자바 코드 상에서는 User객체 자체에 애노테이션을 적용했는데, Hibernate가 자동으로 writer.id를 외래키로 인식하여 설정하는가 보다. 그런데 User의 PK말고, 다른 unique 칼럼을 외래키로 삼을 수는 없는가?

Convert LocalDateTime to TimeStamp

https://thorben-janssen.com/persist-localdate-localdatetime-jpa/

image-20210323020132224

CREATED_DATE_TIME을 보니까 이미 자동으로 TIMESTAMP로 설정이 되어있다.

@Lob

@Lob 은 매우 많은 글자를 저장할 수 있도록 해주는 애노테이션이다.

@Lob Specifies that a persistent property or field should be persisted as a large object to a database-supported large object type.

https://stackoverflow.com/questions/29511133/what-is-the-significance-of-javax-persistence-lob-annotation-in-jpa#:~:text=Lob%20signifies%20that%20the%20annotated,deserialized)%20using%20standard%20Java%20serialization.


수업

https://biz.chosun.com/site/data/html_dir/2009/03/20/2009032000825.html

https://hudi.kr/%EB%B9%84%EB%8F%99%EA%B8%B0%EC%A0%81-javascript-%EC%8B%B1%EA%B8%80%EC%8A%A4%EB%A0%88%EB%93%9C-%EA%B8%B0%EB%B0%98-js%EC%9D%98-%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%B2%98%EB%A6%AC-%EB%B0%A9%EB%B2%95/

https://engineering.huiseoul.com/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%9E%91%EB%8F%99%ED%95%98%EB%8A%94%EA%B0%80-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%A3%A8%ED%94%84%EC%99%80-%EB%B9%84%EB%8F%99%EA%B8%B0-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EC%9D%98-%EB%B6%80%EC%83%81-async-await%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EC%BD%94%EB%94%A9-%ED%8C%81-%EB%8B%A4%EC%84%AF-%EA%B0%80%EC%A7%80-df65ffb4e7e

https://www.slideshare.net/deview/212-large-scale-backend-service-develpment

https://stackoverflow.com/questions/48936624/tcp-when-server-listening-on-random-port-how-does-client-know-which-port-to-sen

https://hofmannsven.com/2019/commit-message-driven-development