1

Hibernateは、OracleのCriterionAPIを使用して日付範囲を誤って処理しているようです。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. ただし、基準の場合、Baraは、対応するSQLクエリよりも約10倍多くのオブジェクトをList<Foo>返します。余分なオブジェクトはすべて同一のコピーです。FooFoo


編集

@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)タイムスタンプ範囲もこのHibernateCriteriaの日付間の制限と一致します。

編集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 に答える