4

私は休止状態が初めてです。選択クエリを実行しようとしているときに問題があります

"from Foo where Foo.some_id=2"

(Hibernate テンプレートを使用) Hibernate は、Foo テーブルと 1 対 1 で関連付けられているテーブル 'Foo2' にレコードを挿入しようとします。

ビーンフー

class Foo{
int id;
....
Foo2 foo2;
}

Foo.hbm.xml

...
<one-to-one name="foo2" class="Foo2" property-ref="foo"
  constrained="false" cascade="save-update"></one-to-one>
...

ビーンフー2

Class Foo2{
...
private int foo;
...
}

Foo2.hbm.xml

...
<property name="foo" column="foo_id"/>
...

使用法

 DetachedCriteria criteria = createDetachedCriteria();
  criteria.add(Restrictions.eq("some_id", value));
  return getHibernateTemplate().findByCriteria(criteria);

    public List<SnsUser> getAllSnsUsersByProperty(String prop, Object val){
            String query = "from SnsUser su where su." + prop + " =:" + prop;
            return executeQuery(query, new String[]{prop}, new Object[]{val});
    }

    public static void main(String[] args) { //WORKING
    String query = "from SnsUser su where su.blessUserId=1";
    Session session = Utility.getSessionFactory().openSession();
    List l = new SnsUserDaoImpl().getQRes(query);
    System.out.println(l);
    session.close();
    }
public List<E> executeQuery(String queryString, String []param, Object [] val){
//NOT WORKING
        return getHibernateTemplate().findByNamedParam(queryString, param, val);
    }   

これは私が得ているものです...

Hibernate: select * from bless_aggregation.sns_user this_ left outer join bless_aggregation.sns_authenticator snsauthent2_ on this_.sns_uid=snsauthent2_.sns_uid 
where this_.bless_uid=?
Hibernate: select * from bless_aggregation.bless_user blessuser0_ where blessuser0_.bless_uid=?
Hibernate: select * from bless_aggregation.sns_user snsuser0_ left outer join bless_aggregation.sns_authenticator snsauthent1_ on 
snsuser0_.sns_uid=snsauthent1_.sns_uid where snsuser0_.bless_uid=?

Hibernate: insert into bless_aggregation.sns_authenticator (key, value, sns_uid) values (?, ?, ?)
1079 [main] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 1064, SQLState: 42000
1079 [main] ERROR org.hibernate.util.JDBCExceptionReporter - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'key, value, sns_uid) values (null, null, 1)' at line 1
4

1 に答える 1

5

私の推測では、セッションに保留中の変更 (いくつかの Foo2 インスタンスが挿入されるのを待っている) があり、デフォルトでは、Hibernate はクエリを実行する前にセッションをフラッシュして、古くない結果を提供します。これについては、ドキュメントの次のセクションで説明されています。

10.10. セッションのフラッシュ

セッションは、JDBC 接続の状態をメモリに保持されているオブジェクトの状態と同期するために必要な SQL ステートメントを実行する場合があります。フラッシュと呼ばれるこのプロセスは、デフォルトで次の時点で発生します。

  • 一部のクエリ実行前
  • org.hibernate.Transaction.commit() から
  • Session.flush() から

SQL ステートメントは、次の順序で発行されます。

  1. を使用して対応するオブジェクトが保存されたのと同じ順序でのすべてのエンティティの挿入Session.save()
  2. すべてのエンティティの更新
  3. すべてのコレクションの削除
  4. すべてのコレクション要素の削除、更新、および挿入
  5. すべてのコレクションの挿入
  6. を使用して対応するオブジェクトが削除されたのと同じ順序でのすべてのエンティティの削除Session.delete()

例外は、ネイティブ ID 生成を使用するオブジェクトが保存時に挿入されることです。

明示的flush()に . ただし、Hibernate は が Query.list(..)古いデータや正しくないデータを返さないことを保証します。

フラッシュがあまり頻繁に発生しないように、デフォルトの動作を変更することができますFlushModeクラスは 3 つの異なるモードを定義します: Hibernate Transaction API が使用されている場合にコミット時にのみフラッシュする、説明されたルーチンを使用して自動的にフラッシュする、または flush() が明示的に呼び出されない限りフラッシュしない。最後のモードは、セッションが長時間開いたままになり、切断されたままになる、長時間実行される作業単位に役立ちます (セクション11.3.2「拡張セッションと自動バージョン管理」を参照してください)。

sess = sf.openSession();
Transaction tx = sess.beginTransaction();
sess.setFlushMode(FlushMode.COMMIT);

// クエリが古い状態を返すことを許可します

Cat izi = (Cat) sess.load(Cat.class, id);
izi.setName(iznizi);

// might return stale data
sess.find("from Cat as cat left outer join cat.kittens kitten");

// change to izi is not flushed!
...
tx.commit(); // flush occurs
sess.close();

フラッシュ中に例外が発生する場合があります (たとえば、DML 操作が制約に違反した場合)。例外の処理には Hibernate のトランザクション動作の理解が必要なので、第 11 章トランザクションと並行性で説明します。

したがって、上記の説明とコード スニペットに示されているように、 を使用してみてくださいFlushMode.COMMIT

identityジェネレーターを使用している場合、これは役に立たないことに注意してください。Hibernate はそのsave時点でデータベースに書き込みます。

また、 は のヒントであり、動作が厳密に保証されているわけではないことに注意FlushModeくださいSession

于 2010-10-10T19:17:42.747 に答える