🍒

SpringbootでJPAの学習中に現れたエラーを2つ紹介。

2025/03/03に公開

はじめに

  • Springboot初学者です。
  • JPAの実装の際に現れた問題についてメモ程度に残していきたいと思います。

使用技術

  • Java17
  • Springboot
  • REST API
  • JPA
  • PostgreSQL
  • lombok

エラーの紹介

  1. ERROR: null value in column "name"
  2. User追加をした内容は"{\n \"name\":\"yamada\"\n}"のようにjsonを正しく受け取れない。

開発内容について

  • Userテーブルにid, nameカラムのみを作っています。
  • ユーザー追加機能のみを実装しています。
User.java
package com.example.demo_jpa.entity;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "users")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
}
UserRepository.java
package com.example.demo_jpa.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.example.demo_jpa.entity.User;

@Repository
public interface UserRepository extends JpaRepository<User, Integer> {
}
UserService.java
package com.example.demo_jpa.service;

import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.demo_jpa.entity.User;
import com.example.demo_jpa.repository.UserRepository;

import lombok.RequiredArgsConstructor;

@Service
@Transactional
@RequiredArgsConstructor
public class UserService {
    private final UserRepository repository;

    public User insert(String name){
        if (name == null || name.trim().isEmpty()) {
            throw new IllegalArgumentException("Name cannot be null or empty");
        }
        User user = new User();
        user.setName(name);
        return repository.save(user);
    }
}
UserController.java
package com.example.demo_jpa.controller;

import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo_jpa.entity.User;
import com.example.demo_jpa.service.UserService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.PostMapping;

@RestController
@RequestMapping("")
public class UserController {
    private final UserService service;

    public UserController(UserService service) {
        this.service = service;
    }
    
    @PostMapping("/register")
    @ResponseStatus(HttpStatus.CREATED)
    public ResponseEntity<User> register(String name) {
        User saveUser = service.insert(name);
        return new ResponseEntity(saveUser, HttpStatus.CREATED);
    }
}
application.yml
spring:
    application:
        name: demo_jpa
    datasource:
        url: jdbc:postgresql://localhost:5432/demojpa
        username: postgres
        password: postgres
        driver-class-name: org.postgresql.Driver
    jpa:
        hibernate:
            ddl-auto: update    # アプリケーション起動時に、Entityに対応するテーブルがなければ作成します。
        show-sql: true      # 実行されるSQLをログに表示する設定。

エラー①について

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.dao.DataIntegrityViolationException: could not execute statement [ERROR: null value in column "name" of relation "users" violates not-null constraint
  詳細: Failing row contains (6, null).] [insert into users (name) values (?)]; SQL [insert into users (name) values (?)]; constraint [name" of relation "users]] with root cause

org.postgresql.util.PSQLException: ERROR: null value in column "name" of relation "users" violates not-null constraint
  詳細: Failing row contains (6, null).
  • エラーの原因は、insert(name)にnullが渡され、データベースのNOT NULL制約に違反しているものと思われます。

解決策:アノテーション忘れ。

  • UserControllerクラスのregisterメソッドの引数に@RequestParamというアノテーションをつけ忘れていました。
  • 初めはつけていたのに何かのタイミングで消していたみたいです…
  • これならもっと早く気づけそうでした…

エラー②について

  • ユーザーを追加したのに下記の内容で登録されてしまいました。
{
    "id": 10,
    "name": "{\n    \"name\":\"hanako\"\n}"
}

解決策:Formクラスを作成する。

  • 引数にUserFormクラスを受け取るようにしました。
UserForm.java
package com.example.demo_jpa.form;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserForm {
    private String name;
}
  • そのようにすると適切にUserを追加することができました。
{
    "id": 12,
    "name": "hanako3"
}
  • 最終的なUserControllerクラスは下記の内容になりました。
UserController.java
package com.example.demo_jpa.controller;

import java.util.List;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo_jpa.entity.User;
import com.example.demo_jpa.form.UserForm;
import com.example.demo_jpa.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

@RestController
@RequestMapping("")
@RequiredArgsConstructor
public class UserController {
    private final UserService service;

    @PostMapping("/register")
    @ResponseStatus(HttpStatus.CREATED)
    public ResponseEntity<User> register(@RequestBody UserForm form) {
        User saveUser = service.insert(form.getName());
        return new ResponseEntity(saveUser, HttpStatus.CREATED);
    }
}

最後に

  • 未熟なエラーですみません。
  • まだまだいろんなことを学んでいきます。
  • 新しいことを知れてよかったです!!!

Discussion