Как исправить ошибку в SimpleJdbcInsert в приложении SpringBoot - PullRequest
0 голосов
/ 24 марта 2019

Я изучаю Spring Boot, читая книгу Spring in Action 5. Я пытаюсь вставить данные во встроенную базу данных H2. Я использую метод SimpleJdbcInsert и executeAndReturnKey.

Вот конструктор:

 @Autowired
public JdbcOrderRepository(JdbcTemplate jdbc) {

this.orderInserter = new SimpleJdbcInsert(jdbc).withTableName("Taco_Order").usingGeneratedKeyColumns("id");
    this.orderTacoInserter = new SimpleJdbcInsert(jdbc).withTableName("Taco_Order_Tacos");
    this.objectMapper = new ObjectMapper();
}

Вот методы для вставки данных:

@Override
public Order save(Order order) {

    order.setPlacedAt(new Date());
    long orderId = saveOrderDetails(order);
    order.setId(orderId);
    List<Taco> tacos = order.getTacos();

    for (Taco taco : tacos)
        saveTacoToOrder(taco, orderId);

    return order;
}

private long saveOrderDetails(Order order) {
    Map<String, Object> values = objectMapper.convertValue(order, Map.class);
    values.put("placedAt", order.getPlacedAt());
    long orderId = orderInserter.executeAndReturnKey(values).longValue();

    return orderId;
}

Ошибка в этой строке:

long orderId = orderInserter.executeAndReturnKey(values).longValue();

Текст ошибки:

 There was an unexpected error (type=Internal Server Error, status=500).
PreparedStatementCallback; ???????? NULL ?? ????????? ??? ???? 
"DELIVERYNAME" NULL not allowed for column "DELIVERYNAME"; SQL statement: 
INSERT INTO Taco_Order (DELIVERYNAME, DELIVERYSTREET, DELIVERYCITY, 
DELIVERYSTATE, DELIVERYZIP, CCNUMBER, CCEXPIRATION, CCCVV, PLACEDAT) 
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?) [23502-197]; nested exception is 
org.h2.jdbc.JdbcSQLException: ???????? NULL ?? ????????? ??? ???? 
"DELIVERYNAME" NULL not allowed for column "DELIVERYNAME"; SQL statement: 
INSERT INTO Taco_Order (DELIVERYNAME, DELIVERYSTREET, DELIVERYCITY, 
DELIVERYSTATE, DELIVERYZIP, CCNUMBER, CCEXPIRATION, CCCVV, PLACEDAT) 
   VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?) [23502-197]

Бур в отладчике, все в порядке: Значение параметра полностью загружается значениями. Идея Screenot

Класс заказа:

@Data
public class Order {

@NotBlank(message = "Name is required")
private String name;

@NotBlank(message = "Name is required")
private String street;

@NotBlank(message = "Name is required")
private String city;

@NotBlank(message = "Name is required")
private String state;

@NotBlank(message = "Name is required")
private String zip;

@CreditCardNumber(message = "Not valid cc")
private String ccNumber;

@Pattern(regexp = "^(0[1-9]|1[0-2])([\\/])([1-9][0-9])$", message = "Must be formatted MM/YY")
private String ccExpiration;

@Digits(integer = 3, fraction = 0, message = "Invalid CVV")
private String ccCVV;

private Long id;
private Date placedAt;

List<Taco> tacos = new ArrayList<>();

public void addDesign(Taco design) {
    this.tacos.add(design);
}

}

Как решить эту проблему и вставить данные в базу данных H2 с помощью SimpleJdbcInsert?

1 Ответ

0 голосов
/ 25 марта 2019

Я прошел снимок экрана и не вижу значения для столбца DELIVERYNAME.

Проблема заключается в том, что таблица, в которой вы выполняете операцию вставки, не допускает нулевые значения для столбца DELIVERYNAME.

способов решить эту проблему: -

  1. Удалите НЕ пустые ограничения из столбца в определении таблицы.

  2. Удалите аннотацию @NotBlank из членов объекта, если вы не уверены, будут ли данные пустыми или нет.

  3. Используйте правильное сопоставление между именами столбцов в таблице и именами элементов в определении класса / сущности. Вы можете использовать аннотацию @Column, чтобы легко это сделать.

Насколько я понимаю, следуя вашему коду и скриншоту, проблема заключается в неправильном отображении имен столбцов и имен членов объекта. Рекомендуется вместо того, чтобы полагаться на автоматическое сопоставление кодера Spring Boot, вручную выполнять сопоставление с помощью аннотации @Column или сопоставления через файл конфигурации hibernate.

...