Post-запрос в Spring Boot Controller выдает «java.sql.SQLIntegrityConstraintViolationException: столбец ‘columnname’ не может быть нулевым»

#java #mysql #spring #spring-boot

#java #mysql #весна #spring-boot

Вопрос:

Я начинаю изучать Spring Boot и в настоящее время пытаюсь написать свой первый API. Конечная точка контроллера для создания новых курсов работает просто отлично (путем отправки объекта JSON через Postman). Однако моя конечная точка для создания новых кандидатов возвращает

 {
    "timestamp": "2020-11-14T15:21:47.189 00:00",
    "status": 500,
    "error": "Internal Server Error",
    "message": "",
    "path": "/demo/addapplicant"
}
  

в Postman и

java.sql.SQLIntegrityConstraintViolationException: столбец «пол» не может быть нулевым

в окне терминала. Когда я меняю свою базу данных MySQL, чтобы разрешить Null для gender, это просто выдает то же исключение для другого атрибута. Я предполагаю, что JSON неправильно переведен в объект Java. Но поскольку он работает для курсов, я не уверен, что вызывает проблему.

Класс-кандидат:

 package com.example.demoSql;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.util.Date;

@Entity
public class Applicant {
  @Id
  @GeneratedValue(strategy=GenerationType.AUTO)
  private Integer id;

  private String firstname;

  private String lastname;
  
  private String gender; //only m, w, d allowed
  
  private Date birthdate;
  
  private String city;
  
  private Integer zip_code;
  
  private String street;
  
  private String housenumber;
  
  private Float highschool_grade;
  
  private String highschool_certificate;

  public Integer getId() {
    return id;
  }

  public void setId(Integer id) {
    this.id = id;
  }

  public String getFirstname() {
    return firstname;
  }

  public void setFirstname(String firstname) {
    this.firstname = firstname;
  }
  
  public String getLastname() {
    return lastname;
  }

  public void setLastname(String lastname) {
    this.lastname = lastname;
  }
  
  public String gender() {
    return gender;
  }

  public void gender(String gender) {
    this.gender = gender;
  }
  
  public Date getBirthdate() {
    return birthdate;
  }

  public void setBirthdate(Date birthdate) {
    this.birthdate = birthdate;
  }

  public String city() {
    return city;
  }

  public void setCity(String city) {
    this.city = city;
  }
  
  public Integer getZipCode() {
    return zip_code;
  }

  public void setZipCode(Integer zip_code) {
    this.zip_code = zip_code;
  }
  
  public String getStreet() {
    return street;
  }

  public void setStreet(String street) {
    this.street = street;
  }
  
  public String getHousenumber() {
    return housenumber;
  }

  public void setHousenumber(String housenumber) {
    this.housenumber = housenumber;
  }
  
  public Float getHighschoolGrade() {
    return highschool_grade;
  }

  public void setHighschoolGrade(Float highschool_grade) {
    this.highschool_grade = highschool_grade;
  }
  
  public String getHighschoolCertificate() {
    return highschool_certificate;
  }

  public void setHighschoolCertificate(String highschool_certificate) {
    this.highschool_certificate = highschool_certificate;
  }
}
  

Контроллер:

 package com.example.demoSql;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller 
@RequestMapping(path="/demo")
public class MainController {
  @Autowired
  private CourseRepository courseRepository;
  @Autowired
  private ApplicantRepository applicantRepository;

  @PostMapping(path="/addcourse")
  public @ResponseBody String addNewCourse (@RequestBody Course course) {
    courseRepository.save(course);
    return "Saved";
  }

  @GetMapping(path="/allcourses")
  public @ResponseBody Iterable<Course> getAllUsers() {
    // This returns a JSON or XML with the courses
    return courseRepository.findAll();
  }
  
  @PostMapping(path="/addapplicant")
  public @ResponseBody String addNewApplicant (@RequestBody Applicant applicant) {
    applicantRepository.save(applicant);
    return "Saved";
  }
}
  

Объект JSON:

 {
    "firstname": "Erik",
    "lastname": "Bosse",
    "gender": "m",
    "city": "Stuttgart",
    "zip_code": 753924,
    "street": "Hauptstraße",
    "housenumber": "24",
    "highschool_grade": 1.5,
    "highschool_certificate": "C://dshfjhsdnsdklgdsl"
}
  

Ответ №1:

После сопоставления из json в java Obejct (заявитель) пол был установлен в null, потому что у вас нет средства получения / установки пола в «Заявителе» :

вам нужно использовать :

       public String getGender() {
        return gender;
      }
    
      public void setGender(String gender) {
        this.gender = gender;
      }
  

вставка :

       public String gender() {
        return gender;
      }

      public void gender(String gender) {
        this.gender = gender;
      }
  

Ответ №2:

  1. Пожалуйста, добавьте свой установщик / получатель пола в ваш POJO. это решит вашу проблему.

  2. Также я вижу, что вы не уверены в теле вашего запроса. В этом случае добавьте аннотацию «@JsonIgnoreProperties (ignoreUnknown = true)» на уровне класса (POJO), чтобы неизвестное поле можно было игнорировать.

  3. также определите тип среды (потребляет / производит) в вашем коде (я имею в виду, какой запрос вы ожидаете от пользователя).