简体   繁体   English

休眠日期时间值不正确

[英]Hibernate Incorrect datetime value

Hoping someone can clear this up for me. 希望有人可以帮我解决这个问题。 I'm getting some warnings when I run a unit test that is using hibernate criteria. 当我运行使用休眠条件的单元测试时,我收到一些警告。 The specific warnings are: 具体警告是:

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

I can't figure out what Hibernate is complaining about. 我不知道Hibernate在抱怨什么。 The column it's talking about, 'date_created', is of type datetime. 它所讨论的列“ date_created”的类型为datetime。 I've tried passing in every other version of the date object, a string, a java.util.Date, a java.sql.Timestamp, but those just cause actual errors. 我尝试传递日期对象的所有其他版本,字符串,java.util.Date,java.sql.Timestamp,但是它们只会引起实际错误。 Specifically they cause: 具体来说,它们会导致:

java.lang.ClassCastException: java.sql.Timestamp cannot be cast to java.lang.Long

or, of course, whatever other type I tried passing instead of Long. 或者,当然,无论我尝试传递的其他任何类型(而不是Long)。 The times I'm passing in are epoch times but for some reason I'm getting these errors and the unit tests aren't passing. 我通过的时间是一个划时代的时间,但是由于某种原因,我遇到了这些错误,并且单元测试没有通过。

Also, in case it might help, here is the specific code in the tests: 另外,如果可能会有所帮助,下面是测试中的特定代码:

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);
}

EDIT Sorry for the delay, here's the requested additions. 编辑抱歉,延迟,这是要求的补充。

@Entity
@Table(name = "content")
public class Content implements Serializable
{
private static final long serialVersionUID = -8483381938400121236L;

public Content()
{
}

public Content(String messageId, ContentBlock block) throws NullPointerException
{
    if(messageId == null || block == null)
        throw new NullPointerException("Null objects passed for Content object creation");
    this.messageId = messageId;
    this.setContentBlock(block);
    this.dateCreated = System.currentTimeMillis();
}

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", columnDefinition = "BIGINT UNSIGNED")
private int id;

@Column(name = "message_id")
private String messageId;

@Column(name = "date_created")
private long dateCreated;

@Column(name = "content_wrapper", columnDefinition = "longblob")
private byte[] contentWrapper;

@ManyToMany(mappedBy = "contentBlocks")
private List<TCollection> collections;

/*@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "message_id")
private TMessage message;*/

I omitted the getters and setters for brevity 为了简洁起见,我省略了getter和setter方法

As for the database, it's got a regular structure. 至于数据库,它有一个规则的结构。 The TContent table has: TContent表具有:

column               type
id                  bigint
user_id             int
name                varchar
date_created        datetime
collection_wrapper  longblob
tspoll_expire       decimal

Please let me know if I can add anything else or have missed anything. 请让我知道我是否可以添加其他内容或错过任何内容。 Thanks for taking a look. 谢谢参观。

In the past I've used the following, which successfully converts between MySQL datetime field and java.util.Date : 过去,我使用了以下代码,该代码成功地在MySQL datetime字段和java.util.Date之间进行转换:

@Temporal(TemporalType.TIMESTAMP)
private Date dateTime;

And more recently with Joda-time , the following successfully converts between MySQL 5.7 datetime(3) and org.joda.time.DateTime : 最近,使用Joda-time ,以下代码成功在MySQL 5.7 datetime(3)和org.joda.time.DateTime之间进行转换:

@Column(columnDefinition = "DATETIME(3)")
private DateTime dateTime;

There will be other options but these are the two I'm currently familiar with. 会有其他选择,但是这是我目前熟悉的两个。

Hibernate has a bug (sort of) when parameter hibernate.hbm2ddl.auto set to update If table contains filed with the same name, for example from previous deployment, it just leave field 'as is' and doesn't change field type. 当参数hibernate.hbm2ddl.auto设置为update时,Hibernate有一个错误(某种)。如果表包含的文件具有相同的名称(例如,来自先前的部署),它将仅保留字段“ as is”,并且不更改字段类型。 I think, previously you set date_created as Date type, but later switch it to long. 我认为,以前您将date_created设置为Date类型,但后来将其切换为long类型。

Possible solutions: 可能的解决方案:

  1. change java bean field type long dateCreated ; 更改java bean字段类型long dateCreated ; to Date dateCreated; Date dateCreated; and work with Date type in code. 并在代码中使用日期类型。
  2. manually change database structure accordinly to your java classes. 根据您的java类手动更改数据库结构。 alter table content alter column date_created TYPE bigint I doesn't sure mysql allow to do it, in that case you should write migration procedure. alter table content alter column date_created TYPE bigint我不确定mysql是否允许这样做,在这种情况下,您应该编写迁移过程。
  3. drop database and recreate it with hibernate (only if content not important/test/garbage) 删除数据库并使用休眠方式重新创建它(仅当内容不重要/测试/垃圾时)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM