2011-10-18 18 views
0

ループ内でネイティブクエリを実行しようとすると、クエリは正しいSQL構文を表示しますが、出力は常に同じです。ループ内でnativeQueryを実行すると正しいデータが返されない

Hibernate: Select * from translation1 
Hibernate: Select * from translation2 
Hibernate: Select * from translation3 

が、「行」変数は常に、すなわち行translation1テーブルの最初のSELECT文の結果が含まれています

for (int i=0; i<translations.size(); i++) { 
     Query query = entityManager.createNativeQuery("Select * from " + translations.get(i).getName(), MyModel.class); 
     rows = (List<MyModel>)query.getResultList(); 
     // rest of the function... 
    } 

は今コンソールに私は次のようにHibernateの文を見ることができます。

コンソールで、他のテーブルからも選択していることを示す理由はありますが、実際には常にtranslation1テーブルからデータを取得しますか?

+0

をください呼び出すことにより、セッションのキャッシュをクリアこれらのテーブルのidフィールドの値は同じですか? – axtavt

+0

他にも 'rows'が使われていることを見ずにこれに答えることは本当に不可能です。たとえば、なぜ 'rows'がforループ内で宣言されていないのですか? –

+0

@axtavtはいすべてのテーブルは、1つの列rowTextを除き、同じIDおよび同じ列名を持ちます。これは、転換表に応じて異なる言語のテキストを含みます。 – Rizwan

答えて

2

が、それは予想される動作です。

Hibernateセッションキャッシュは、セッション内に特定のIDを持つ特定のタイプのエンティティのインスタンスが1つしか存在しないことを保証します。エンティティはネイティブクエリの場合でもセッションキャッシュを介して解決されるため、同じインスタンスが取得されます。

だから、あなたはいくつかのオプションがあります:

  • データベースシェマを再考がクエリ結果からオブジェクトを構築し、手動で
  • 強制的にあなたがclear()またはdetach()
+0

助けてくれてありがとう、私はdbスキーマを変更できません、entityManager.clear()は問題を修正しました。 – Rizwan

+0

@ user908452: 'clear()'は、セッションキャッシュからすべてのエンティティを削除します。これらのエンティティの一部が別のメソッドによって読み込まれた場合、予期しない副作用が発生する可能性があります。おそらく、 'detach()'を使って、ロードしたばかりのエンティティだけを明示的に削除するほうがいいでしょう。 – axtavt

0

rows変数に実際に返された結果のLASTが含まれていないことを確認してください。どのように行を初期化するのですか?ループ内の変数を使って何をしますか?すべてのクエリからすべての結果を取得する場合は、ループ内で各ループを追加する必要がある場合は、ループが開始する前に宣言されたリスト/セット変数に追加します。

それともあなたには、いくつかの適切なSQLを使用して行うことができ:すべてのテーブルはIDの同じセットを持っている場合

SELECT * FROM Table1 [JOIN/UNION] Table2 etc... 
+0

私は行変数が最後のデータを含んでいないと確信しています、私はループの外でそれを初期化していました - しかし、私もループの内部でそれを初期化しようとし、それでも動作しませんでした。 ArrayListの行を繰り返してマップのマップに追加します。 – Rizwan