Java中java.util.Date类型DOB插入数据库始终为1970-01-01求助
出生日期(DOB)存入数据库始终为1970-01-01的解决方法
问题背景
Postman固定请求JSON格式如下:
{ "DOB":"20101123" }
预期存入数据库的日期格式为2010-11-23,但实际每次都会存入1970-01-01,且项目限制无法修改java.util.Date数据类型。
问题原因
DTO类EmployeeInformation中DOB字段为java.util.Date类型,但请求传递的是**yyyyMMdd格式的字符串日期**。Jackson默认的日期解析器无法识别这种格式,解析失败后会生成时间戳为0的Date对象,对应日期就是1970-01-01。
解决方案
方案1:添加日期格式化注解(最简单直接)
在EmployeeInformation的DOB字段上添加@JsonFormat注解,指定输入日期的格式:
@Data public class EmployeeInformation { // 其他字段保持不变... @JsonProperty(value = "DOB") @JsonFormat(pattern = "yyyyMMdd", timezone = "GMT+8") // 时区根据业务需求调整 private Date DOB; }
添加该注解后,Jackson会按照指定格式解析字符串,生成正确的Date对象,存入数据库后就是预期的日期。
方案2:自定义日期反序列化器(注解不适用时使用)
如果注解方式无法满足特殊需求,可以自定义反序列化逻辑:
- 编写自定义反序列化器类:
public class CustomDateDeserializer extends StdDeserializer<Date> { private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMdd"); public CustomDateDeserializer() { this(null); } public CustomDateDeserializer(Class<?> vc) { super(vc); } @Override public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { String dateStr = jsonParser.getText(); try { return DATE_FORMAT.parse(dateStr); } catch (ParseException e) { throw new RuntimeException("日期格式错误,需为yyyyMMdd格式", e); } } }
- 在DTO的
DOB字段上指定使用该反序列化器:
@JsonProperty(value = "DOB") @JsonDeserialize(using = CustomDateDeserializer.class) private Date DOB;
额外检查项
- 确认数据库表的
dob字段类型为DATE,避免因字段类型不匹配导致存储异常 - 检查Updater类的更新逻辑:如果存在新旧日期
equals判断不生效的情况(比如时间精度问题),需要单独处理Date类型的比较:
修改Updater的update方法中的判断逻辑:public <T> Updater update(String fieldName, Function<EmployeeInformation, T> newValueGetter, Function<OrgEmployeeMap, T> oldValueGetter, BiConsumer<OrgEmployeeMap, T> oldValueSetter) { final var newValue = newValueGetter.apply(information); final var oldValue = oldValueGetter.apply(existing); if (newValue == null) { return this; } // 针对Date类型单独处理比较逻辑 if (newValue instanceof Date && oldValue instanceof Date) { Date newDate = (Date) newValue; Date oldDate = (Date) oldValue; Calendar newCal = Calendar.getInstance(); newCal.setTime(newDate); Calendar oldCal = Calendar.getInstance(); oldCal.setTime(oldDate); // 仅比较年、月、日是否一致 boolean sameDate = newCal.get(Calendar.YEAR) == oldCal.get(Calendar.YEAR) && newCal.get(Calendar.MONTH) == oldCal.get(Calendar.MONTH) && newCal.get(Calendar.DAY_OF_MONTH) == oldCal.get(Calendar.DAY_OF_MONTH); if (sameDate) { return this; } } else if (newValue.equals(oldValue)) { return this; } this.updatedFields.add(fieldName); oldValueSetter.accept(existing, newValue); return this; }
内容的提问来源于stack exchange,提问作者dracile
相关产品推荐
相关产品推荐

