JPA-参数值[604800000]与类型[java.lang.Double]不匹配

JPA-参数值[604800000]与类型[java.lang.Double]不匹配,java,hibernate,postgresql,jpa,Java,Hibernate,Postgresql,Jpa,我尝试从一个超过给定时间(以天为单位)的表中删除行。行的开始是一个时间戳 EntityManager em = ... long interval = ... // long value read from a properties file String template = "DELETE FROM %s WHERE current_timestamp() - start > :interval"; String jpql = String.format(template , MyC

我尝试从一个超过给定时间(以天为单位)的表中删除行。行的
开始
是一个时间戳

EntityManager em = ...
long interval = ... // long value read from a properties file

String template = "DELETE FROM %s WHERE current_timestamp() - start > :interval";
String jpql = String.format(template , MyClass.class.getCanonicalName());

Query q = em.createQuery(jpql);
q.setParameter("interval", TimeUnit.DAYS.toMillis(interval));
q.executeUpdate();
MyClass.java

@Entity
@Table(name = "ROWS")
public class MyClass implements Serializable {

    private static final long serialVersionUID = 6070604872038740340L;

    puyblic MyClass() {
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name = "start", columnDefinition="TIMESTAMP WITH TIME ZONE")
    @Temporal(TemporalType.TIMESTAMP)
    private Date start;

    // getters ans setters...
}
但是,我得到以下例外情况:

原因:java.lang.IllegalArgumentException:参数值[604800000]与类型[java.lang.Double]不匹配 位于org.hibernate.ejb.AbstractQueryImpl.registerParameterBinding(AbstractQueryImpl.java:360) 位于org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:364) 位于org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:72)


我做错了什么?

请查看HSQL。问题可能与currentTimestamp和start有关。我不能认为它是HSQL关键字或有效属性

您是否尝试过使用未命名参数并使用其索引设置参数

更新

您的设置似乎不正确。您希望使用字符串(开始)进行算术计算

我最近也做了类似的事情。我只是有一个任务,我设置了时间,然后检查任务是否超时(没有完成,但时间戳比之前小)

下面是一些代码:

1/映射

long timestamp = 0; //default is 0
2/设置时间戳

task.setTimestamp(System.currentTimeMillis()); session.getTransaction().commit()
3/查询超时方法

   session.beginTransaction();
   long currentTime = System.currentTimeMillis();
   Criteria criteria = session.createCriteria(Task.class);
   criteria.add(Restrictions.eq("done", false));
   criteria.add(Restrictions.le("timestamp", currentTime - Task.TASK_TIMEOUT));
   Task task = (Task)criteria.uniqueResult();
   if(task != null) {
        task.setTimestamp(currentTime);
   }
   session.getTransaction().commit();

您可以看到,我只是在这里使用条件搜索,因为它更简单。还请注意,我使用uniqueResult,但您可以轻松地将其更改为检索列表。

请查看HSQL。问题可能与currentTimestamp和start有关。我不能认为它是HSQL关键字或有效属性

您是否尝试过使用未命名参数并使用其索引设置参数

更新

您的设置似乎不正确。您希望使用字符串(开始)进行算术计算

我最近也做了类似的事情。我只是有一个任务,我设置了时间,然后检查任务是否超时(没有完成,但时间戳比之前小)

下面是一些代码:

1/映射

long timestamp = 0; //default is 0
2/设置时间戳

task.setTimestamp(System.currentTimeMillis()); session.getTransaction().commit()
3/查询超时方法

   session.beginTransaction();
   long currentTime = System.currentTimeMillis();
   Criteria criteria = session.createCriteria(Task.class);
   criteria.add(Restrictions.eq("done", false));
   criteria.add(Restrictions.le("timestamp", currentTime - Task.TASK_TIMEOUT));
   Task task = (Task)criteria.uniqueResult();
   if(task != null) {
        task.setTimestamp(currentTime);
   }
   session.getTransaction().commit();

您可以看到,我只是在这里使用条件搜索,因为它更简单。还请注意,我使用uniqueResult,但您可以轻松地将其更改为检索列表。

答案非常简单

String template=“从%s中删除,其中当前\u timestamp()-start>:interval”
生成此查询Hibernate希望此间隔值的类型为Double

因此,这样做可以解决您的问题:

q.setParameter("interval", (double)TimeUnit.DAYS.toMillis(interval));
我们都希望Java能够在需要时从long转换为double。但是,由于long值是装箱的,Hibernate只是试图将long值转换为Double,这一点也没有效果

所以如果你先把它转换成双倍,它会被装箱成双倍,双倍显然是可以转换成双倍的

那么双打是从哪里来的呢?

我检查了SqlDate和Date类型的实现,它们都映射到Date,并且能够从和转换为长值。时间戳也映射到日期

所以我试了一下:

String template=“从%s中删除,其中当前时间戳()>:interval”
它失败了,因为Hibernate抱怨Long与java.util.Date不兼容。因此,仅使用current_timestamp()映射到日期值

这一点也是如此:

String template=“从%s开始删除>:interval”

当一个人试图从另一个日期中减去一个日期时,双精度开始发挥作用。因此,使用以下任何一种:
String template=“从%s中删除,其中当前时间戳()-当前时间戳()>:间隔”
String template=“从%s开始删除-开始>:interval”

由于Date-Date的结果应为双精度值,因此间隔应为双精度值。这就是Hibernate抱怨的原因


有点奇怪,但事实就是这样,这就是发生了什么的确切解释。

答案很简单

String template=“从%s中删除,其中当前\u timestamp()-start>:interval”
生成此查询Hibernate希望此间隔值的类型为Double

因此,这样做可以解决您的问题:

q.setParameter("interval", (double)TimeUnit.DAYS.toMillis(interval));
我们都希望Java能够在需要时从long转换为double。但是,由于long值是装箱的,Hibernate只是试图将long值转换为Double,这一点也没有效果

所以如果你先把它转换成双倍,它会被装箱成双倍,双倍显然是可以转换成双倍的

那么双打是从哪里来的呢?

我检查了SqlDate和Date类型的实现,它们都映射到Date,并且能够从和转换为长值。时间戳也映射到日期

所以我试了一下:

String template=“从%s中删除,其中当前时间戳()>:interval”
它失败了,因为Hibernate抱怨Long与java.util.Date不兼容。因此,仅使用current_timestamp()映射到日期值

这一点也是如此:

String template=“从%s开始删除>:interval”

当一个人试图从另一个日期中减去一个日期时,双精度开始发挥作用。因此,使用以下任何一种:
String template=“从%s中删除,其中当前时间戳()-当前时间戳()>:间隔”
String template=“从%s开始删除-开始>:interval”

由于Date-Date的结果应为双精度值,因此间隔应为双精度值。这就是Hibernate抱怨的原因


有点奇怪,但事实就是这样,这就是发生了什么的确切解释。

这里是我如何解决问题的:

而不是做ca