Внешний ключ является нулевым: Hibernate Spring - PullRequest
0 голосов
/ 16 марта 2020

Я пытаюсь сохранить объект Run в базу данных. Я определил отношения между бегом и городом. В одном городе может быть много трасс. У меня проблема с city_id. Нулевой.

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause
java.sql.SQLIntegrityConstraintViolationException: Column 'city_id' cannot be null

Мои объекты и контроллер: Город

@Entity
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "cities")
public class City {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "city_id")
    private long id;
    @OneToMany(mappedBy = "city", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<Run> runs = new ArrayList<>();
    private String name;
}

Запуск

@Entity
@Builder
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "runs")
public class Run {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    @Column(name = "name_run")
    private String nameRun;
    @Column(name = "distance")
    private double distance;
    @Column(name = "date")
    private Date date;
    @Column(name = "my_time")
    private String myTime;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "city_id", nullable = false)
    @OnDelete(action = OnDeleteAction.CASCADE)
    @JsonIgnore
    private City city;
}

Контроллер


@CrossOrigin
@RestController
@RequestMapping("/api/")
public class RunController {

    private RunRepository runRepository;
    private RunService runService;

    public RunController(RunRepository runRepository, RunService runService) {
        this.runRepository = runRepository;
        this.runService = runService;
    }

    @GetMapping("runs")
    public ResponseEntity<List<Run>> getRuns() {
        return runService.getRuns();
    }

    @PostMapping("runs")
    public ResponseEntity addRun(@RequestBody Run run) {

        return new ResponseEntity<>(runRepository.save(run), HttpStatus.OK);
    }
}

Я хотел бы сохранить запустить в БД. Мой тестовый запрос выглядит следующим образом:

{"nameRun": "test", "distance": "5.0", "date": "2020-12-12", "myTime": "50:40" , "city": "test1"}

Результат вычисления выражения в Intelijj:

enter image description here

Почему City = null? Здесь ошибка в отображении?

Ответы [ 3 ]

1 голос
/ 16 марта 2020

Можете попробовать с этим json, но вам нужно передать идентификатор города в json.

{
    "nameRun": "test",
    "distance": "5.0",
    "date": "2020-12-12",
    "myTime": "50:40",
    "city": {
        "id": 1,
        "name": "test1"
    }
}

Спасибо

0 голосов
/ 16 марта 2020

если вы хотите сохранить любой класс выполнения,

Run run = new Run();
City city = new City();
city.getRuns().add(run);
runRepository.save(run);

если вы хотите сохранить любой класс выполнения, сначала вам нужно вставить в (Arraylist) переменную запуска класса города, например city.getRuns ( ) .add (run) после заполнения run, тогда вы можете запуститьRepository.save (run).

Также мои примеры здесь. Вы можете посмотреть на мои классы.

Первый класс называется Пациент .

@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@ToString
@Table(name = "aapatient")
public class Patient {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "AA_PATIENT_SEQ")
    @SequenceGenerator(sequenceName = "AA_PATIENT_SEQ", allocationSize = 1, name = "AA_PATIENT_SEQ")
    @Column(name = "patientid")
    private Long patientid;
    private String name;
    private String lastname;  

    @OneToMany(mappedBy = "patient", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<Problem> problems; 
}

Второй класс называется Это проблема .

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Entity
@Table(name="aaproblem")
public class Problem{

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "AA_PATIENT_SEQ")
    @SequenceGenerator(sequenceName = "AA_PATIENT_SEQ", allocationSize = 1, name = "AA_PATIENT_SEQ")
    @Column(name = "problemid")
    private Long problemid;
    private String problemName;
    private String problemDetail; 

    @Temporal(TemporalType.TIMESTAMP)
    Date creationDate;

    @NotNull
    @ManyToOne(optional = true, fetch = FetchType.LAZY)
    @JoinColumn(name = "patient_id")
    private Patient patient;

}
0 голосов
/ 16 марта 2020

Прежде всего, используйте Long для id, пожалуйста. Лучше добавить также @Entity аннотацию.

@Entity
public class City {

    @Id
    @GeneratedValue
    private Long id;

    @OneToMany(mappedBy = "city", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<Run> runs = new ArrayList<>();

}

@Entity
public class Run {

    @Id
    @GeneratedValue
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    private City city;

}

Вам нужно установить city_id при сохранении Run.

Самый простой способ сделать это - просто создать фальшивый переходный процесс City и присвоить ему идентификатор.

City city = new City();
city.setId(1L);

Run run = new Run();
run.setCity(city);

repository.save(run);

Очевидно, у вас должен быть город с id 1L в базе данных.

Другие варианты

  1. Используйте что-то вроде session.load() Hibernate-аналог с репозиторием Spring для создания City без загрузки его из базы данных.
  2. Загрузка City объекта полностью по id.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...