【问题标题】:Unable to save entity when date is set设置日期时无法保存实体
【发布时间】:2019-10-18 06:26:55
【问题描述】:

我正在使用带有 JPA 和 Lombok 的 Spring Boot。 我的 Sample 实体包含四个日期,批准 日期、样品日期,以及由 JPA 自己使用 Auditable 类维护的 createdAtmodifiedAt。 JPA 管理模式、运行 MySQL 的数据库,所有日期列都是DateTime。所有日期都属于java.util.Date

示例实体(出于某种原因进行了简化)

@Entity
@Data
@EqualsAndHashCode(callSuper = false)
public class Sample extends Auditable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Integer id;

    Date approved;

    @DateTimeFormat(pattern = "yyyy-MM-dd'T'H:m")
    Date sampleDate;
}

sampleDate 上的DateTimeFormat 是为了帮助 Spring 将表单数据转换为 java.util.Date

Auditable.java

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class Auditable {

    @CreatedDate
    @Column(name = "created_at", updatable = false, nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date createdAt;

    @LastModifiedDate
    @Column(name = "modified_at")
    @Temporal(TemporalType.TIMESTAMP)
    private Date modifiedAt;
}

当我的控制器执行此操作时:

Sample s = sampleRepository.getOne(id);
s.setApproved(new Date());
sampleRepository.save(s);

Spring 生成此错误消息:

com.mysql.cj.jdbc.exceptions.MysqlDataTruncation:数据截断:第 1 行的“已批准”列的数据太长

【问题讨论】:

  • 示例数据库模式的外观如何?
  • approved 列的最大长度是多少?

标签: java mysql spring spring-data-jpa


【解决方案1】:

如果您使用 java >= 8 执行此操作,最好使用 LocalDateTime 而不是 java.util.Datejava.sql.Date

被审计实体的 createdDate、lastModifiedDate 应该由 Jpa Auditor(framework) 设置,而不是由客户端(在这种情况下,您)设置。

另外,如果您想保留您的代码,可以尝试使用@Temporal(TemporalType.DATE) 而不是TemporalType.TIMESTAMP

更新

抱歉,我错过了您提出的确切主题。

只需尝试在Date approved; 上方添加@Temporal(TemporalType.DATE)

【讨论】:

  • 不要使用LocalDateTime。它没有描述您几乎肯定想要的时间点,特别是对于Auditable 中的字段。改为考虑Instant
  • @JensSchauder 从不同的角度来看,我同意你的建议。但是,对于本地服务,使用LocalDateTime 更容易读取时间。我认为这个论点在这个问题上是不恰当的。
猜你喜欢
  • 1970-01-01
  • 2016-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-27
相关资源
最近更新 更多