Java 休眠错误的日期时间值

Java 休眠错误的日期时间值,java,spring,hibernate,datetime,spring-data,Java,Spring,Hibernate,Datetime,Spring Data,希望有人能帮我澄清。当我运行使用hibernate标准的单元测试时,我收到一些警告。具体警告如下: Mar 10, 2016 11:48:31 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper$StandardWarningHandler logWarning WARN: SQL Warning Code: 1292, SQLState: 22007 Mar 10, 2016 11:48:31 AM org.hibernate.engine.

希望有人能帮我澄清。当我运行使用hibernate标准的单元测试时,我收到一些警告。具体警告如下:

Mar 10, 2016 11:48:31 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper$StandardWarningHandler logWarning
WARN: SQL Warning Code: 1292, SQLState: 22007
Mar 10, 2016 11:48:31 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper$StandardWarningHandler logWarning
WARN: Incorrect datetime value: '1454684370' for column 'date_created' at row 1
Mar 10, 2016 11:48:31 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper$StandardWarningHandler logWarning
WARN: SQL Warning Code: 1292, SQLState: 22007
Mar 10, 2016 11:48:31 AM  org.hibernate.engine.jdbc.spi.SqlExceptionHelper$StandardWarningHandler logWarning
WARN: Incorrect datetime value: '1454684700' for column 'date_created' at row 1
我不明白Hibernate在抱怨什么。它所说的“date_created”列的类型是datetime。我尝试过传入date对象的每个其他版本,一个字符串、一个java.util.date、一个java.sql.Timestamp,但这些只会导致实际错误。具体而言,它们导致:

java.lang.ClassCastException: java.sql.Timestamp cannot be cast to java.lang.Long
或者,当然,我尝试过的其他类型的传球,而不是长传。我所传递的时间是大纪元时间,但由于某种原因,我得到了这些错误,而单元测试没有通过

此外,如果可能有帮助,以下是测试中的特定代码:

public List<Content> findByCollectionName(String collectionName, Long exclusiveBegin, Long inclusiveEnd, Long expiration)
{
    if(collectionName == null)
        return null;

    Session session = currentSession();
    session.beginTransaction();
    Criteria criteria = session.createCriteria(Content.class).setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
    criteria.createAlias("collections", "cols");
    criteria
        .add(Restrictions.and(Restrictions.eq("cols.name", collectionName), buildCriterion(exclusiveBegin, inclusiveEnd, expiration)));

    List<Content> list = criteria.list();

    session.getTransaction().commit();

    return list;
}

private Criterion buildCriterion(Long exclusiveBegin, Long inclusiveEnd, Long expiration)
{
    List<Criterion> criterion = new ArrayList<Criterion>();
    if(exclusiveBegin != null)
        criterion.add(Restrictions.gt("dateCreated", exclusiveBegin));
    if(inclusiveEnd != null)
        criterion.add(Restrictions.le("dateCreated", inclusiveEnd));
    if(expiration != null)
        criterion.add(Restrictions.ge("dateCreated", expiration));

    Criterion[] array = new Criterion[criterion.size()];
    for(int j = 0; j < array.length; j++)
    {
        array[j] = criterion.get(j);
    }

    return Restrictions.and(array);
}

请让我知道我是否可以添加任何其他内容或遗漏任何内容。感谢您的关注。

在过去,我使用了以下方法,成功地在MySQL datetime字段和
java.util.Date
之间转换:

@Temporal(TemporalType.TIMESTAMP)
private Date dateTime;
最近,在MySQL 5.7 datetime(3)和
org.joda.time.datetime
之间成功地实现了以下转换:

@Column(columnDefinition = "DATETIME(3)")
private DateTime dateTime;
还有其他选项,但这些是我目前熟悉的两个。

当参数
Hibernate.hbm2ddl.auto
设置为
update
时,Hibernate有一个bug(某种程度上),如果表中包含具有相同名称的字段,例如从以前的部署中,它只保留字段“原样”,并且不更改字段类型。 我想,以前您将
date\u created
设置为日期类型,但后来将其切换为long

可能的解决办法:

  • 更改JavaBean字段类型
    longDateCreated
    ;到
    创建日期并在代码中使用日期类型
    
  • 根据java类手动更改数据库结构
    altertable content alter column date\u created TYPE bigint
    我不确定mysql是否允许这样做,在这种情况下,您应该编写迁移过程
  • 删除数据库并使用hibernate重新创建它(仅当内容不重要/测试/垃圾时)

  • 您是否尝试过使用@TemporalType(TIMESTAMP)(可能需要也可能不需要)注释列,然后使用java.sql.TIMESTAMP?正如我所提到的,尝试除Long之外的任何操作都会导致错误。更明确地说,它会导致ClassCastException,表示无论它是什么,都不能转换为长时间。所以这必须是一个漫长的过程。问题是为什么hibernate不接受它。你能发布你的模型吗?请为
    内容
    类和该类的数据库表结构添加映射。像这里的其他注释一样,我认为问题在于映射问题(注释或XML文件)。你能在这里发布你的映射吗?我更深入地研究了模型类,datetime变量很长,所以这很可能是问题的主要原因。我将它重构为一个时间戳,它似乎至少开始使用hibernate。所以我想这就是答案。谢谢你的帮助,谢谢。我相信你是对的,这基本上就是问题所在。很抱歉,钱伯斯先生的回答虽然有点迂回,但已经引导到了那个答案,所以我已经接受了他的解决方案。谢谢你的帮助。
    
    @Temporal(TemporalType.TIMESTAMP)
    private Date dateTime;
    
    @Column(columnDefinition = "DATETIME(3)")
    private DateTime dateTime;