一千萬個為什麽

搜索

HQLを使用した選択カウントが矛盾した結果を返す

さて、私は現在、NetBeans 7.2.1、Hibernate 3.2.5、GlassFish 3.1.2.2、およびMySQL 5.5.20を使用してJSF 2.1プロジェクトに取り組んでいます。

私は、一度クリックすると、テーブルにエントリを追加するボタンを持っています。ページをリフレッシュすると、ボタンが以前に押されたかどうかに基づいて、別の要素が色を変えます。これは、ボタンがエントリを挿入したテーブルの select count(*)

私の問題は、 select count(*)がリフレッシュごとに矛盾した結果を返すということです。クエリは、自分の where 句とテーブルデータに応じて常に0または常に1のいずれかを返すはずですが、データが変更されていなくても最初の挿入物。

たとえば、MySQL Workbenchで手動で select count(*)クエリを実行すると、ページボタンを使用して最初に挿入された後に常に1が返されます。一方、Hibernateはリフレッシュごとにランダムに0または1を返します。以下の例では、各コンマがリフレッシュされています:1,0,1,0,0,1,0,0,0,0,1,0,0,1,1,0

count が一貫した結果を返さない理由を誰かが知っていますか?それはキャッシングの問題なのでしょうか?

If I restart my project in NetBeans and I access the same page again, then it always returns 1 as expected.

さらなるテストでは、トランザクション自體が正常にコミットされているにもかかわらず、JDBC接続が「コミットされていない」狀態にあることに関連しているように見えます。

私の問題があまり明確でない場合はお詫び申し上げます。私はむしろ混亂しています。


コードを挿入する:

public boolean reserveBook(int memberId, String isbn)
{
    boolean done = false;

    Transaction tx = null;

    try
    {
        tx = session.beginTransaction();

        Member m = new Member();
        m.setMemberId(memberId);

        Book b = new Book();
        b.setIsbn(isbn);

        Reservation r = new Reservation();
        r.setMember(m);
        r.setBook(b);
        r.setDate(new Date());

        session.save(r);
        tx.commit();

        done = true;
    }
    catch (Exception e)
    {
        if (tx != null)
        {
            tx.rollback();
        }

        e.printStackTrace(System.out);
    }

    return done;
}

カウントコード:

public boolean isBookReserved(int memberId, String isbn)
{
    boolean answer = false;

    String reqHQL = "select count(*) " +
                    "from Reservation R " +
                    "where R.member = :memberId and R.book = :isbn";

    try
    {
        session.beginTransaction();
        Query q = session.createQuery(reqHQL);

        q.setParameter("memberId", memberId);
        q.setParameter("isbn", isbn);

        if ((Long) q.uniqueResult() > 0)
        {
            answer = true;
        }
    }
    catch (Exception e)
    {
        e.printStackTrace(System.out);
    }

    return answer;
}

クラスヘッダー:

public class BookHelper
{
    private Session session;

    public BookHelper()
    {
        this.session = HibernateUtil.getSessionFactory().getCurrentSession();
    }
    ...

ビーンヘッダー:

@ManagedBean
@RequestScoped
public class BookBean implements Serializable
{
...

最佳答案

あなたと起こっているこの狀況は非常に奇妙です。 COUNTは機能するはずです。

コードをデバッグして、各選択実行でパラメータが常に同じかどうかを確認してください。

PS: there are a closed issue on Hibernate where happened something like that, but in different environments: https://hibernate.atlassian.net/browse/HHH-2945

轉載註明原文: HQLを使用した選択カウントが矛盾した結果を返す