1

Hibernate 似乎使用 Oracle 中的 Criterion API 错误地处理日期范围。SQL 查询本身似乎是正确的(从 Hibernate 复制并手动执行)。所以,

给定

Clazz<Bar> clazz;
Date start, end; 

失败了

List<Bar> bars = sessionFactory.getCurrentSession()
    .createCriteria(clazz)
    .add(Restrictions.between("timestamp", start, end))
    .list();

和这个

 List<Bar> bars = sessionFactory.getCurrentSession()
     .createCriteria(clazz)
     .add(Restrictions.ge("timestamp", start))
     .add(Restrictions.le("timestamp", end))
     .list();

但这有效

List<Bar> bars = sessionFactory.getCurrentSession()
    .createQuery("from Bar b where b.timestamp > ? and b.timestamp < ?")
    .setDate(0, start)
    .setDate(1, end)
    .list();

失败观察是:

  1. Bar返回的结果数相同(且正确)

  2. 但在标准情况下,Bar带有 a 的 aList<Foo>返回的对象大约是相应 SQL 查询的10 倍。Foo所有额外的Foo对象都是相同的副本。


编辑

@Entity
public class Bar {

    @Id 
    private String id;

    @Temporal(TemporalType.TIMESTAMP)
    private Date timestamp;

    @ManyToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER)
    @JoinTable(
        name = "bar_foo",
        joinColumns = { @JoinColumn(name = "barid") },
        inverseJoinColumns = { @JoinColumn(name = "fooid") }
    )
    private List<Foo> params;
}
@Entity
public class Foo {
    @Id private String id;
}
4

2 回答 2

0

尝试重写查询

List<Bar> bars = sessionFactory.getCurrentSession()
 .createCriteria(Bar.class)
 .add(Restrictions.ge("timestamp", start))
 .add(Restrictions.le("timestamp", end))
 .list();

这和你做的一样,但我从来没有见过像你这样使用它们的类类型变量的例子。

您还应该检查此链接HQL(hibernate) 时间戳范围与Hibernate Criteria 中日期的此限制之间的匹配

编辑 2:查看此处的示例:http ://www.javalobby.org/articles/hibernatequery102/

于 2011-12-12T17:56:02.527 回答
0

我现在不记得或查找这背后的基本原理,但您所看到的可能是预期的行为。尝试这个:

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
于 2011-12-12T21:23:53.177 回答