인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

jaemm님의 프로필 이미지

작성한 질문수

스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판

게시글 CRUD API 구현

sqlExceptionHelper null 문제

작성

·

131

·

수정됨

0

createTest 실행시 오류 발생

 

createTest에서 500 오류가 떠서 보니

 

스프링애플리케이션을 실행하면

java.lang.NullPointerException: Cannot invoke "org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(java.sql.SQLException, String)" because the return value of "org.hibernate.resource.transaction.backend.jdbc.internal.JdbcIsolationDelegate.sqlExceptionHelper()" is null
	at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcIsolationDelegate.delegateWork(JdbcIsolationDelegate.java:116) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
	at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.getJdbcEnvironmentUsingJdbcMetadata(JdbcEnvironmentInitiator.java:290) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
	at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:123) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
	at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:77) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
	at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:130) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:238) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:215) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
	at org.hibernate.boot.model.relational.Database.<init>(Database.java:45) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
	at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.getDatabase(InFlightMetadataCollectorImpl.java:221) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
	at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:189) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
	at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:171) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
	at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1431) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
	at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1502) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
	at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:75) ~[spring-orm-6.1.11.jar:6.1.11]

2025-03-05T23:27:34.720+09:00  WARN 50007 --- [jamm-board-article-service] [           main] org.hibernate.orm.deprecation            : HHH90000025: MySQLDialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
2025-03-05T23:27:35.162+09:00  INFO 50007 --- [jamm-board-article-service] [           main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
2025-03-05T23:27:35.163+09:00  INFO 50007 --- [jamm-board-article-service] [           main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2025-03-05T23:27:35.564+09:00  INFO 50007 --- [jamm-board-article-service] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 9000 (http) with context path '/'
2025-03-05T23:27:35.570+09:00  INFO 50007 --- [jamm-board-article-service] [           main] jamm.board.article.ArticleApplication    : Started ArticleApplication in 3.381 seconds (process running for 3.717)

다음과 같은 오류가 뜨네요 ㅜ 제가 폴더명을 다르게 했는데 문제가 있는 걸까요 어떤 게 문제인지 잘 모르겠습니다. 분명히 도커로 mysql도 띄었고 jdbc 연결이 안된걸까요

 

  server.port: 9000
spring:
  application:
    name: jamm-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: true
    hibernate:
      ddl-auto: none

logging:
  level:
    org.hibernate.SQL: DEBUG
    org.hibernate.type.descriptor.sql.BasicBinder: TRACE

 

 


public class ArticleApiTest {
    RestClient restClient = RestClient.create("http://localhost:9000");

    @Test
    void createTest() {
        ArticleResponse response = create(new ArticleCreateRequest(
                "hi", "my content", 1L, 1L
        ));
        System.out.println("response = " + response);
    }

    ArticleResponse create(ArticleCreateRequest request) {
        return restClient.post()
                .uri("/v1/articles")
                .body(request)
                .retrieve()
                .body(ArticleResponse.class);
    }

    @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;
    }


}

 

application.yml (article)

@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);
    }

    @PostMapping("/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);
    }
}

 

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')
    implementation project(':common:outbox-message-relay')
    implementation project(':common:event')
}

 

rootProject.name = 'jamm-board'

include 'common'
include 'common:snowflake'
include 'common:data-serializer'
include 'common:event'
include 'common:outbox-message-relay'
include 'service'
include 'service:article'
include 'service:comment'
include 'service:view'
include 'service:like'
include 'service:hot-article'
include 'service:article-read'

 

docker ps

CONTAINER ID   IMAGE          COMMAND                   CREATED             STATUS         PORTS                               NAMES
ea2f15b15cee   mysql:8.0.38   "docker-entrypoint.s…"   About an hour ago   Up 4 minutes   0.0.0.0:3306->3306/tcp, 33060/tcp   kuke-board-mysql
스크린샷 2025-03-05 오후 11.22.14.png

..

2025-03-05 23:02:20 2025-03-05T14:02:20.281045Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.38' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL.

 

 

  •  

  • 학습 관련 질문을 최대한 상세히 남겨주세요!

  • 고민 과정도 같이 나열해주셔도 좋습니다.

  • 먼저 유사한 질문이 있었는지 검색해보세요.

  • 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.

답변 1

0

쿠케님의 프로필 이미지
쿠케
지식공유자

jaemm님, 안녕하세요!

 

애플리케이션 실행 시점에 해당 에러가 뜨는 것이죠!?

터미널에 아래 명령어 실행해보시겠어요?

lsof -i:3306

실행 결과가 어떻게 될까요?

jaemm님의 프로필 이미지
jaemm
질문자

sudo lsof -i:3306

Password:

|COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME

mysqld 552 _mysql 21u IPv6 0xf04b347f7743fb65 0t0 TCP *:mysql (LISTEN)

이렇게 뜹니다 !

쿠케님의 프로필 이미지
쿠케
지식공유자

혹시 지금도 컨테이너 실행중인 상태가 맞을까요?

도커 컨테이너 실행 중인 상태에서 명령어가 입력된게 맞는지 확인드려봅니다!

컨테이너 생성 시에 mysql 비밀번호 root로 설정했는지, DB/테이블도 잘 생성되어 있는지 점검 해보시겠어요?!

jaemm님의 프로필 이미지
jaemm
질문자

이 부분은 제가 3306으로 로컬 mysql 띄우고 있어서 포트 포워딩을 3307로 해결하고,

createdAt으로 철자 바꿔서 다음장에 테스트 값도 DB에 저장을 하였는데 


500 Internal Server Error: "{"timestamp":"2025-03-06T15:47:18.859+00:00","status":500,"error":"Internal Server Error","path":"/v1/articles/121530268440289280"}"
org.springframework.web.client.HttpServerErrorException$InternalServerError: 500 Internal Server Error: "{"timestamp":"2025-03-06T15:47:18.859+00:00","status":500,"error":"Internal Server Error","path":"/v1/articles/121530268440289280"}"
	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 jamm.board.article.api.ArticleApiTest.read(ArticleApiTest.java:38)
	at jamm.board.article.api.ArticleApiTest.readTest(ArticleApiTest.java:30)
	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)


500 Internal Server Error: "{"timestamp":"2025-03-06T15:47:18.949+00:00","status":500,"error":"Internal Server Error","path":"/v1/articles/121530268440289280"}"
org.springframework.web.client.HttpServerErrorException$InternalServerError: 500 Internal Server Error: "{"timestamp":"2025-03-06T15:47:18.949+00:00","status":500,"error":"Internal Server Error","path":"/v1/articles/121530268440289280"}"
	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 jamm.board.article.api.ArticleApiTest.read(ArticleApiTest.java:38)
	at jamm.board.article.api.ArticleApiTest.updateTest(ArticleApiTest.java:44)
	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)


500 Internal Server Error: "{"timestamp":"2025-03-06T15:47:18.968+00:00","status":500,"error":"Internal Server Error","path":"/v1/articles"}"
org.springframework.web.client.HttpServerErrorException$InternalServerError: 500 Internal Server Error: "{"timestamp":"2025-03-06T15:47:18.968+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 jamm.board.article.api.ArticleApiTest.create(ArticleApiTest.java:25)
	at jamm.board.article.api.ArticleApiTest.createTest(ArticleApiTest.java:14)
	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)

이런 오류가 뜨네요 ㅜㅜ

 

-parameters도 해보고 gradle로도 해봤는데 다시 좀 봐야할 것 같습니다.

 

추가적으로 서버는 잘 작동되네요

무슨 문제인지는 잘 모르겠습니다..

2025-03-07T00:49:01.824+09:00  INFO 91472 --- [jamm-board-article-service] [           main] jamm.board.article.ArticleApplication    : Starting ArticleApplication using Java 21.0.6 with PID 91472 (/Users/jaemm/Desktop/work/hello-spring/jamm-board/service/article/build/classes/java/main started by jaemm in /Users/jaemm/Desktop/work/hello-spring/jamm-board)
2025-03-07T00:49:01.825+09:00  INFO 91472 --- [jamm-board-article-service] [           main] jamm.board.article.ArticleApplication    : No active profile set, falling back to 1 default profile: "default"
2025-03-07T00:49:02.139+09:00  INFO 91472 --- [jamm-board-article-service] [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2025-03-07T00:49:02.165+09:00  INFO 91472 --- [jamm-board-article-service] [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 22 ms. Found 1 JPA repository interface.
2025-03-07T00:49:02.435+09:00  INFO 91472 --- [jamm-board-article-service] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 9000 (http)
2025-03-07T00:49:02.442+09:00  INFO 91472 --- [jamm-board-article-service] [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2025-03-07T00:49:02.443+09:00  INFO 91472 --- [jamm-board-article-service] [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.26]
2025-03-07T00:49:02.476+09:00  INFO 91472 --- [jamm-board-article-service] [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2025-03-07T00:49:02.476+09:00  INFO 91472 --- [jamm-board-article-service] [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 624 ms
2025-03-07T00:49:02.557+09:00  INFO 91472 --- [jamm-board-article-service] [           main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
2025-03-07T00:49:02.586+09:00  INFO 91472 --- [jamm-board-article-service] [           main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.5.2.Final
2025-03-07T00:49:02.605+09:00  INFO 91472 --- [jamm-board-article-service] [           main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
2025-03-07T00:49:02.804+09:00  INFO 91472 --- [jamm-board-article-service] [           main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
2025-03-07T00:49:02.819+09:00  INFO 91472 --- [jamm-board-article-service] [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2025-03-07T00:49:03.028+09:00  INFO 91472 --- [jamm-board-article-service] [           main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl@cf10c92
2025-03-07T00:49:03.029+09:00  INFO 91472 --- [jamm-board-article-service] [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2025-03-07T00:49:03.065+09:00  WARN 91472 --- [jamm-board-article-service] [           main] org.hibernate.orm.deprecation            : HHH90000025: MySQLDialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
2025-03-07T00:49:03.523+09:00  INFO 91472 --- [jamm-board-article-service] [           main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
2025-03-07T00:49:03.525+09:00  INFO 91472 --- [jamm-board-article-service] [           main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2025-03-07T00:49:03.882+09:00  INFO 91472 --- [jamm-board-article-service] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 9000 (http) with context path '/'
2025-03-07T00:49:03.889+09:00  INFO 91472 --- [jamm-board-article-service] [           main] jamm.board.article.ArticleApplication    : Started ArticleApplication in 2.271 seconds (process running for 2.673)
jaemm님의 프로필 이미지
jaemm
질문자

test 코드는

public class ArticleApiTest {
    RestClient restClient = RestClient.create("http://localhost:9000");

    @Test
    void createTest() {
        ArticleResponse response = create(new ArticleCreateRequest(
                "hi", "my content", 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(121530268440289280L);
        System.out.println("response = " + response);
    }

    ArticleResponse read(Long articleId) {
        return restClient.get()
                .uri("/v1/articles/{articleId}", articleId)
                .retrieve()
                .body(ArticleResponse.class);
    }

    @Test
    void updateTest() {
        update(121530268440289280L);
        ArticleResponse response = read(121530268440289280L);
        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}", 121530268440289280L)
                .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;
    }
}

이 형식입니다.

쿠케님의 프로필 이미지
쿠케
지식공유자

테스트 코드에서 500 에러 응답 받는건 클라이언트 입장에서 나타나는거라 자세한 로그가 남지 않습니다!

상세한 로그를 보려면 로컬에서 실행중인 서버 애플리케이션의 로그를 보셔야 합니다!

위 내용만으로는 저도 파악이 쉽지 않네요..!

에러가 나는 시점의 서버 애플리케이션 로그를 살펴보시겠어요?

jaemm님의 프로필 이미지

작성한 질문수

질문하기