게시판 CRUD 관련 오류
학습 관련 질문을 최대한 상세히 남겨주세요!
고민 과정도 같이 나열해주셔도 좋습니다.
먼저 유사한 질문이 있었는지 검색해보세요.
인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
안녕하세요,
저와 비슷한 오류가 많은 것 같은데 해결이 안된것 같아서 질문드립니다.
13분쯤에 코드를 같이 따라 쳐보도 위와 같은 오류가 발생합니다.
이문제가 해결이 안되서 코드만 3번째 다시 치고 있습니다 ㅠㅠ...
500 Internal Server Error: "{"timestamp":"2025-03-03T03:54:49.747+00:00","status":500,"error":"Internal Server Error","path":"/v1/articles"}"
org.springframework.web.client.HttpServerErrorException$InternalServerError: 500 Internal Server Error: "{"timestamp":"2025-03-03T03:54:49.747+00:00","status":500,"error":"Internal Server Error","path":"/v1/articles"}"
at org.springframework.web.client.HttpServerErrorException.create(HttpServerErrorException.java:102)
at org.springframework.web.client.StatusHandler.lambda$defaultHandler$3(StatusHandler.java:89)
at org.springframework.web.client.StatusHandler.handle(StatusHandler.java:146)
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.applyStatusHandlers(DefaultRestClient.java:698)
at org.springframework.web.client.DefaultRestClient.readWithMessageConverters(DefaultRestClient.java:200)
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.readBody(DefaultRestClient.java:685)
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.body(DefaultRestClient.java:631)
at kuke.board.article.api.ArticleApiTest.create(ArticleApiTest.java:29)
at kuke.board.article.api.ArticleApiTest.createTest(ArticleApiTest.java:16)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
https://velog.io/@ghwns9991/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-3.2-%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98-%EC%9D%B4%EB%A6%84-%EC%9D%B8%EC%8B%9D-%EB%AC%B8%EC%A0%9C
스프링 3.2 부터 uri 관련 매개변수 어노테이션을 잘 인식하지 못한다고 하나 봅니다. 저는 윗 글의 두 번째(-parameters) 방법으로 해결했습니다.
위와 같이 해결했다고 하는 문구가 많은데,
저는 -parameters를 추가해도 같은 오류가 발생합니다.

혹시 추가 설정이 필요한 부분이나 추가적으로 말씀해주시면 업로드 하겠습니다 !
코드 추가
ArticleController
package kuke.board.article.controller;
import kuke.board.article.service.ArticleService;
import kuke.board.article.service.request.ArticleCreateRequest;
import kuke.board.article.service.request.ArticleUpdateRequest;
import kuke.board.article.service.response.ArticleResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
@RestController
@RequiredArgsConstructor
public class ArticleController {
private final ArticleService articleService;
@GetMapping("/v1/articles/{articleId}")
public ArticleResponse read(@PathVariable Long articleId) {
return articleService.read(articleId);
}
@PostMapping("/v1/articles")
public ArticleResponse create(@RequestBody ArticleCreateRequest request) {
return articleService.create(request);
}
@PutMapping("/v1/articles/{articleId}")
public ArticleResponse update(@PathVariable Long articleId, @RequestBody ArticleUpdateRequest request) {
return articleService.update(articleId, request);
}
@DeleteMapping("/v1/articles/{articleId}")
public void delete(@PathVariable Long articleId) {
articleService.delete(articleId);
}
}
entity-Article
package kuke.board.article.entity;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.time.LocalDateTime;
@Table(name = "article")
@Getter
@Entity
@ToString
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Article {
@Id
private Long articleId;
private String title;
private String content;
private Long boardId;
private Long writerId;
private LocalDateTime createAt;
private LocalDateTime modifiedAt;
public static Article create(Long articleId, String title, String content, Long boardId, Long writerId) {
Article article = new Article();
article.articleId = articleId;
article.title = title;
article.content = content;
article.boardId = boardId;
article.writerId = writerId;
article.createAt = LocalDateTime.now();
article.modifiedAt = article.createAt;
return article;
}
public void update(String title, String content) {
this.title = title;
this.content = content;
modifiedAt = LocalDateTime.now();
}
}
repository - ArticleRepository
package kuke.board.article.repository;
import kuke.board.article.entity.Article;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ArticleRepository extends JpaRepository<Article, Long> {
}
Service - request - ArticleCreateRequest
package kuke.board.article.service.request;
import lombok.Getter;
import lombok.ToString;
@Getter
@ToString
public class ArticleCreateRequest {
private String title;
private String content;
private Long writerId;
private Long boardId;
}Service - request - ArticleUpdateRequest
package kuke.board.article.service.request;
import lombok.Getter;
import lombok.ToString;
@Getter
@ToString
public class ArticleUpdateRequest {
private String title;
private String content;
}
Service - response - ArticleResponse
package kuke.board.article.service.response;
import kuke.board.article.entity.Article;
import lombok.Getter;
import lombok.ToString;
import java.time.LocalDateTime;
@Getter
@ToString
public class ArticleResponse {
private Long articleId;
private String title;
private String content;
private Long boardId;
private Long writerId;
private LocalDateTime createAt;
private LocalDateTime modifiedAt;
public static ArticleResponse from(Article article) {
ArticleResponse response = new ArticleResponse();
response.articleId = article.getArticleId();
response.title = article.getTitle();
response.content = article.getContent();
response.boardId = article.getBoardId();
response.writerId = article.getWriterId();
response.createAt = article.getCreateAt();
response.modifiedAt = article.getModifiedAt();
return response;
}
}ArticleApplication
package kuke.board.article;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ArticleApplication {
public static void main(String[] args) {
SpringApplication.run(ArticleApplication.class, args);
}
}resources - application.yml
server:
port: 9000
spring:
application:
name: kuke-board-article-service
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/article
username: root
password: root
jpa:
database-platform: org.hibernate.dialect.MySQLDialect
open-in-view: false
show-sql: false
hibernate:
ddl-auto: none
test - java - kuke.board.article.api
package kuke.board.article.api;
import kuke.board.article.service.request.ArticleCreateRequest;
import kuke.board.article.service.response.ArticleResponse;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.autoconfigure.web.client.RestClientTest;
import org.springframework.web.client.RestClient;
public class ArticleApiTest {
RestClient restClient = RestClient.create("http://localhost:9000");
@Test
void createTest() {
ArticleResponse response = create(new ArticleCreateRequest(
"hi", "my contents", 1L, 1L
));
System.out.println("response = " + response);
}
ArticleResponse create(ArticleCreateRequest request) {
return restClient.post()
.uri("/v1/articles")
.body(request)
.retrieve()
.body(ArticleResponse.class);
}
@Test
void readTest() {
ArticleResponse response = read(1234L);
System.out.println("response = " + response);
}
ArticleResponse read(Long articleId) {
return restClient.get()
.uri("/v1/articles/{articleId}")
.retrieve()
.body(ArticleResponse.class);
}
@Test
void updateTest() {
update(1234L);
ArticleResponse response = read(1234L);
System.out.println("response = " + response);
}
void update(Long articleId) {
restClient.put()
.uri("/v1/articles/{articleId}", articleId)
.body(new ArticleUpdateRequest("hi 2", "my content 22"))
.retrieve()
;
}
@Test
void deleteTest() {
restClient.delete()
.uri("/v1/articles/{articleId}", 1234L)
.retrieve();
}
@Getter
@AllArgsConstructor
static class ArticleCreateRequest {
private String title;
private String content;
private Long writerId;
private Long boardId;
}
@Getter
@AllArgsConstructor
static class ArticleUpdateRequest {
private String title;
private String content;
}
}article - build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.mysql:mysql-connector-j'
implementation project(':common:snowflake')
}
답변 6
2
전부 createAt이 아니라 createdAt으로 바꿔도 동일하신가용?
return restClient.get() .uri("/v1/articles/{articleId}") .retrieve() .body(ArticleResponse.class);
여기 부분에서 uri("v1/articles/{articleId}", articleId) 이렇게 넘겨주셔야 하는데 인자 넘기는게 비어있는 것도 확인해보시면 좋을 것 같아요
2
혹시 아티클 엔티티에 createAt이라고 하셨는데 쿠케님이 올려주신 DDL에는 created_at으로 되어있습니다. 이 부분에서 컬럼 매핑이 정상적으로 안되는 것은 아닐지.....
1
서버 로그에서
org.hibernate.exception.SQLGrammarException: JDBC exception executing SQL [select a1_0.article_id,a1_0.board_id,a1_0.content,a1_0.create_at,a1_0.modified_at,a1_0.title,a1_0.writer_id from article a1_0 where a1_0.article_id=?] [Unknown column 'a1_0.create_at' in 'field list'] [n/a]
와 같은 로그를 찾아서 필드명 다시 확인했습니다. 감사합니다 !
1
초보 초보 개발자님, 안녕하세요!
올려주신 에러 로그는 테스트 코드가 서버에게 응답 받은 에러 로그입니다!
그래서 클라이언트 입장에서 서버의 응답 코드를 받기만 한거라 자세한 로그가 남지 않습니다.
테스트 코드의 실행 로그를 봐야하는 것이 아니라, 실행 중인 서버 애플리케이션의 로그를 봐야 합니다.
서버 애플리케이션의 에러 로그를 확인해보시겠어요?!
1
안녕하세요, 인프런 AI 인턴입니다. 초보 초보 개발자님.
스프링 부트 기반으로 게시판 CRUD 작업을 하시면서 “500 Internal Server Error”가 발생하고 있어 어려움을 겪고 계신 것 같습니다. 이 오류는 서버 코드에서 발생하는 문제를 의미하며, 디버깅을 통해 문제의 근본 원인을 찾아야 합니다.
오류 해결을 위한 검토 사항:
서버 로그 확인:
- 콘솔이나 로그 파일에서 자세한 예외 메시지를 확인해보세요. Java에서는
stack trace를 통해 문제의 원인을 파악할 수 있습니다. 특히 어디에서 예외가 발생했는지를 찾아보는 것이 중요합니다.
- 콘솔이나 로그 파일에서 자세한 예외 메시지를 확인해보세요. Java에서는
애플리케이션 설정 파일 확인:
application.yml또는application.properties에서 설정이 잘못되거나 누락된 부분이 없는지 확인하세요. 특히 데이터베이스 연결 정보와 서버 포트 설정이 올바른지 재확인해보세요.
@PathVariable 및 @RequestParam 어노테이션 확인:
- 엔드포인트의 컨트롤러 메소드에서 사용하는 어노테이션이 올바르게 적용되어 있는지 확인합니다. URI 경로 변수와 메소드 인자간의 매칭이 정확한지 확인하세요.
-parameters옵션은 매개 변수 정보를 런타임에 사용할 수 있도록 하는 역할을 합니다.
- 엔드포인트의 컨트롤러 메소드에서 사용하는 어노테이션이 올바르게 적용되어 있는지 확인합니다. URI 경로 변수와 메소드 인자간의 매칭이 정확한지 확인하세요.
디버깅 및 예외 핸들링:
- 실행 시 예외가 발생할 수 있는 부분에서
try-catch를 이용해 보다 구체적인 예외를 핸들링해보세요. 이를 통해 어떤 입력 혹은 상태에서 문제가 발생하는지 확인할 수 있습니다.
- 실행 시 예외가 발생할 수 있는 부분에서
관련 문제 참고:
- 스프링 3.2 부터의 매개변수 인식 문제와 해결 방법 링크를 참고하세요. 메소드 시그니처와 어노테이션 간의 불일치를 해결하는 방법에 대한 힌트를 얻을 수 있습니다.
- 스프링 3.2 부터의 매개변수 인식 문제와 해결 방법 링크를 참고하세요. 메소드 시그니처와 어노테이션 간의 불일치를 해결하는 방법에 대한 힌트를 얻을 수 있습니다.
위의 방법으로도 문제가 해결되지 않는다면, 테스트 코드가 호출하는 API의 경로와 데이터 구조까지 함께 검토해보시는 것을 추천합니다. 추가적인 로그나 예외 메시지를 제공해주시면 더 많은 도움을 드릴 수 있습니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
consumer에서 에러가 발생할 경우 데이터 유실 문의
0
43
2
게시글 테스트 데이터 삽입
0
48
2
정렬, 필터, 검색 등의 조건이 붙을 경우 최적화할 수 있는 방법이 무엇이 있을까요?
0
100
2
좋아요 기능 정합성 보장 방법
0
93
2
좋아요 동시성처리 최적의 선택?
1
124
2
프론트엔드 msa 환경 api 주소 통합? 과 서버끼리 통신 방식에대해
0
89
2
안녕하세요 무한스크롤 강의듣다가 질문이 있습니다.
0
57
1
조회수 조회 로직 질문
1
67
2
비로그인 유저도 어뷰징 방지 정책
1
67
2
CommentServiceTest의 테스트 로직 질문
0
53
2
무한 스크롤 방식에서 페이지 번호 방식 쿼리의 문제점 의문
1
72
2
path 쿼리 관련 질문드립니다!
0
59
2
antigravity 에디터를 쓰신다면 종료해주세요
1
122
0
프로젝트 구조
0
86
2
article_like_count api test
0
76
2
이벤트 페이로드 객체의 생성 방식이 팩토리 메서드 패턴이 아닌 빌더 패턴인 이유가 궁금합니다!.
0
103
2
[33. 좋아요 수 구현] 에서 테스트 하는 화면 동시성 문제
0
89
2
findByPath에서 articleId로도 검색을 해야 할 것 같아요.
0
89
3
jpa ddl-auto none을 하는 이유와 join 방법
0
96
2
팩터리 메소드와 response 객체 사용 이유가 궁금합니다!
0
90
2
커서 기반 페이지네이션 과 무한 스크롤링
0
104
2
게시글 생성 로직에서 오류 발생시 redis 게시글 수 되돌리기
0
97
2
멀티 모듈이 아닌 MSA 환경에서 common
0
150
2
2Depth 강의 도중 궁금한 점 있어요!!
0
73
2





