我在Spring 5中学习Spring Boot阅读书。我尝试将数据插入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]
调试器中的Bur没问题: value参数已由值完全加载。 idea screensot
班级顺序:
@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);
}
}
如何解决此问题并使用SimpleJdbcInsert将数据插入H2数据库?
答案 0 :(得分:1)
我今天也遇到同样的问题。我能够解决这个问题。
要解决此问题,请转到schema.sql(要在其中创建表的文件)并从Taco_Order表中的字段中删除传递。
从书中
SimpleJdbcInsert具有执行插入的几个有用方法:execute()和executeAndReturnKey()。两者都接受一个Map,其中map键对应于数据插入到的表中的列名。映射值将插入到这些列中。
键名称是Order.java中的字段
答案 1 :(得分:0)
我经历了屏幕截图,但看不到DELIVERYNAME列的任何值。
问题是由于运行插入操作的表不允许DELIVERYNAME列为空值。
解决此问题的方法:-
从表定义的列中删除“非空”约束。
如果不确定数据是否为空白,请从对象的成员中删除@NotBlank注释。
在“表”中的列名与“类/实体定义”中具有成员名的列名之间使用正确的映射。您可以使用@Column注释轻松地做到这一点。
根据您的代码和屏幕截图,据我所知,该问题是由于列名与对象成员之间的映射不正确引起的。 建议不要使用Spring Boot编码器的自动映射,而应使用@Column注释或通过休眠配置文件进行映射来手动进行映射。
答案 2 :(得分:0)
问题出在Order类中。这些应该反映相应表的列名。 例如:
私有字符串deliveryName; ->将映射到db中的deliveryName字段。
问题已经出现,因为在schema.sql中,该字段被命名为“ deliveryName”,而在配料类中,服装被命名为“ name”。
答案 3 :(得分:0)
这个答案是给那些遵循《春天在行动》一书中的例子的人的。在现实生活中您不会做这种事情,但是如果您是这本书的读者,可以替换掉它:
Map<String, Object> values = objectMapper.convertValue(order, Map.class);
values.put("placedAt", order.getPlacedAt());
与此:
Map<String,Object> values = new HashMap<>();
values.put("ID", order.getId());
values.put("PLACEDAT", order.getPlacedAt());
values.put("DELIVERYNAME", order.getName());
values.put("DELIVERYSTREET", order.getStreet());
values.put("DELIVERYCITY", order.getCity());
values.put("DELIVERYSTATE", order.getState());
values.put("DELIVERYZIP", order.getZip());
values.put("CCNUMBER", order.getCcNumber());
values.put("CCEXPIRATION", order.getCcExpiration());
values.put("CCCVV", order.getCcCVV());
先前的答案提到更改模式,如果您将遵循下一章中的示例或使用jpa注释执行映射,则将导致问题,但是根据该书的作者,您不了解它们,因为它们将在下一章中介绍。章节。此外,您将不在下一章中使用JdbcOrderRepository类。
答案 4 :(得分:0)
Order类中的字段名称必须与表Taco_Order中的列名称相同。
@Data
public class Order {
private Long id;
private Date placedAt;
@NotBlank(message = "Podanie imienia i nazwiska jest obowiazkowe")
private String deliveryName;
@NotBlank(message = "Podanie ulicy jest obowiązkowe")
private String deliveryStreet;
@NotBlank(message = "Podanie miasta jest obowiązkowe")
private String deliveryCity;
@NotBlank(message = "Podanie województwa jest obowiązkowe")
private String deliveryState;
@NotBlank(message = "Podanie kodu pocztowego jest obowiązkowe")
private String deliveryZip;
@CreditCardNumber(message = "To nie jest prawidłowy numer karty kredytowej")
private String ccNumber;
@Pattern(regexp = "^(0[1-9]|1[0-2])([\\/])([1-9][0-9])$", message = "Wartość musi być w formacie MM/RR")
private String ccExpiration;
@Digits(integer = 3, fraction = 0, message = "Nieprawidłowy kod CVV")
private String ccCVV;
public List<Taco> tacos = new ArrayList<>();
public void addDesign(Taco design) {
this.tacos.add(design);
}
public List<Taco> getTacos() {
return tacos;
}
}
答案 5 :(得分:0)
我今天遇到了同样的问题,我忘记做的只是将 order.html 文件中的字段更新为 deliveryName、deliveryCity 等。