기존에 글을 작성하면 views값이 자동으로 0으로 초기화 되지않아서 생성 시도 시, 400 에러 발생
package com.example.backend_B.entity;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Getter
@Entity
public class Article {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String content;
private String author; // 작성자명 받을 필드
private Integer views; // 정수형을 객체로 받았다. wrapper class))
public void patch(Article article) {
if (article.title != null) {
this.title = article.title;
}
if (article.content != null) {
this.content = article.content;
}
if (article.author != null) {
this.author= article.author;
}
}
public void increaseViews() {
this.views++;
}
}
기존 int views로 선언했던것을 Wrapper클래스로 선언해주었다.
private Integer views로 수정하였다.
Wrapper 클래스.
발생한 에러 요약
MethodArgumentNotValidException: Validation failed ...
Field error in object 'articleForm' on field 'views': rejected value [null];
default message [Failed to convert value of type 'null' to required type 'int']
원인
▶views 필드가 int (원시형)인데, HTML <form>에서 값이 아예 전달되지 않아서 Spring이 null을 int로 바꾸지 못하고 예외 발생
즉, views 값이 <form>에서 넘어오지 않으면 → null → 그런데 Java 원시형 int에는 null이 들어갈 수 없음 → 400 Bad Request 발생
기존에 설정은 Default값이 0으로 잘 설정되어있는 것을 볼 수 있었다. (mysql, db에서 확인)
mysql> SHOW COLUMNS FROM article LIKE 'views';
+-------+------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------+------+-----+---------+-------+
| views | int | YES | | 0 | |
+-------+------+------+-----+---------+-------+
1 row in set (0.00 sec)
근데 딱 보면 NULL값이 허용되도록 정해져있었다... not null 속성이어야한다!
그래서 추가해주었다.
mysql> ALTER TABLE article MODIFY views INT NOT NULL DEFAULT 0;
Query OK, 0 rows affected (0.11 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> SHOW COLUMNS FROM article LIKE 'views';
+-------+------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------+------+-----+---------+-------+
| views | int | NO | | 0 | |
+-------+------+------+-----+---------+-------+
1 row in set (0.00 sec)
Article.java
package com.example.backend_B.entity;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Getter
@Entity
public class Article {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String content;
private String author; // 작성자명 받을 필드
private int views = 0 ; //db에 저장되는값은 null없이 0부터 시작하게...
public void patch(Article article) {
if (article.title != null) {
this.title = article.title;
}
if (article.content != null) {
this.content = article.content;
}
if (article.author != null) {
this.author= article.author;
}
}
public void increaseViews() {
this.views+= 1;
}
}
ArticleController.java show부분 메서드만 수정했습니다!
@GetMapping("/articles/{id}")
public String show(@PathVariable Long id, Model model) { // 매개변수로 id 받아 오기
log.info("id = " + id); // id를 잘 받았는지 확인하는 로그 찍기
// 1. id를 조회해 데이터 가져오기
Article articleEntity = articleRepository.findById(id).orElse(null);
if (articleEntity != null) {// 잘 가져왔다면~
articleEntity.increaseViews();
articleRepository.save(articleEntity); //저장
}
List<CommentDto> commentsDtos = commentService.comments(id);
// 2. 모델에 데이터 등록하기
model.addAttribute("article", articleEntity);
model.addAttribute("commentDtos", commentsDtos); // 댓글 목록 모델에 등록
// 3. 뷰 페이지 반환하기
return "articles/show";
}
ArticleForm
package com.example.backend_B.dto;
import com.example.backend_B.entity.Article;
import lombok.AllArgsConstructor;
import lombok.ToString;
@AllArgsConstructor
@ToString
public class ArticleForm {
private Long id;
private String title; // 제목을 받을 필드
private String content; // 내용을 받을 필드
private String author; // 작성자명 받을 필드
private Integer views; // 기본형 -> Wrapper형으로 변경
public Article toEntity() {
int safeViews = (views == null )? 0 : views;
return new Article(id, title, content, author, safeViews);
}
}
new.mustache파일에 작성자명 넣는 칸을 새로 추가해주었습니다.
{{>layouts/header}}
<form class="container" action="/articles/create" method="post">
<div class="mb-3">
<label class="form-label">제목</label>
<input type="text" class="form-control" name="title">
</div>
<div class="mb-3">
<label class="form-label">작성자</label>
<input type="text" class="form-control" name="author">
</div>
<div class="mb-3">
<label class="form-label">내용</label>
<textarea class="form-control" rows="3" name="content"></textarea>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
<a href="/articles">Back</a>
</form>
{{>layouts/footer}}'백엔드 공부(BE, AWS)' 카테고리의 다른 글
| [SpringBoot3]JPA - fetch 타입 (0) | 2025.09.24 |
|---|---|
| 25.07.02 생성시각 삽입 (0) | 2025.07.02 |
| 게시판 CRUD 인기순 정렬(조회수기반) (0) | 2025.07.02 |
| 기존 mysql 수정 (0) | 2025.06.29 |
| (최종과제)Redis 캐시 사용하기 (0) | 2025.06.29 |