使用CrudRepository将ZonedDateTime转换为MySQL时间戳

时间:2015-11-06 20:41:08

标签: java mysql spring spring-data

我有以下代码(为简洁起见而简化):

@Entity
@Table(name="mytable", schema="schemaName")
public class MobileDeviceData {
    @Id
    @Column(name="id")
    private String id;

    @Column(name="activitydetecteddate")
    private ZonedDateTime activityDetectedDate;
}

由Springboot实现的CrudRepository接口:

@Transactional
    public interface MobileDeviceDataDao extends CrudRepository<MobileDeviceData, String> {
}

在activitydetecteddate表中使用Timestamp列字段。

当我尝试通过调用

将其保存到数据库时
mobileDeviceDataDao.save(mobileDeviceDataList);

我收到以下错误:

2015-11-06 11:57:53.095  WARN 3198 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 1292, SQLState: 22001
2015-11-06 11:57:53.095 ERROR 3198 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper   : Data truncation: Incorrect datetime value: '\xAC\xED\x00\x05sr\x00\x0Djava.time.Ser\x95]\x84\xBA\x1B"H\xB2\x0C\x00\x00xpw\x15\x06\x00\x00\x07\xDF\x0B\x06\x10 \x05;?<\x80\x0' for column 'activityDetectedDate' at row 1
2015-11-06 11:57:53.096  INFO 3198 --- [nio-8080-exec-1] o.h.e.j.b.internal.AbstractBatchImpl     : HHH000010: On release of batch it still contained JDBC statements
2015-11-06 11:57:53.097  WARN 3198 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Warning Code: 1292, SQLState: 22007
2015-11-06 11:57:53.097  WARN 3198 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper   : Incorrect datetime value: '\xAC\xED\x00\x05sr\x00\x0Djava.time.Ser\x95]\x84\xBA\x1B"H\xB2\x0C\x00\x00xpw\x15\x06\x00\x00\x07\xDF\x0B\x06\x10 \x05;?<\x80\x0' for column 'activityDetectedDate' at row 1
2015-11-06 11:57:53.108 ERROR 3198 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : 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]; nested exception is org.hibernate.exception.DataException: could not execute statement] with root cause

com.mysql.jdbc.MysqlDataTruncation: Data truncation: Incorrect datetime value: '\xAC\xED\x00\x05sr\x00\x0Djava.time.Ser\x95]\x84\xBA\x1B"H\xB2\x0C\x00\x00xpw\x15\x06\x00\x00\x07\xDF\x0B\x06\x10 \x05;?<\x80\x0' for column 'activityDetectedDate' at row 1
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3868)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3806)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2470)

有人可以告诉我我做错了什么以及如何将代码从ZonedDateTime正确转换为Timestamp。

2 个答案:

答案 0 :(得分:3)

我能够找到解决此问题的解决方案,该解决方案不需要代码中的Hibernate特定注释。我能够通过将这三个罐子添加到类路径中来实现这一点(我使用Gradle):

https://rally1.rallydev.com/slm/webservice/v2.0/User/<userOid>/UserPermissions

然后Hibernate能够正确处理新的Java8类型。

答案 1 :(得分:2)

问题是您的基础JPA提供程序不知道如何序列化该类型。我和我的实体使用joda时间,我有这个问题。我发现的解决方案是使用Hibernate @Type注释,虽然我确定有一种JPA方式可以做到这一点(而不是我使用的提供者特定的注释)。所以你要做的是:

@Type(type ="org.hibernate.type.ZonedDateTimeType")
@Column(name="activitydetecteddate")
private ZonedDateTime activityDetectedDate;

这将告诉Hibernate用于翻译的类。

修改如果你想要一个便携式转换器(即没有绑定),@Convert似乎是你想要使用的注释(基于this答案)休眠)虽然我怀疑你必须提供自己的转换器,但在某些时候你必须将自己绑定到某些特定的