2011-10-18 33 views
0

我想在循環中運行本機查詢,查詢顯示正確的sql語法,但輸出始終是相同的。在循環中運行nativeQuery不會返回正確的數據

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的語句,如:

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

但是變量「行」總是包含第一個SELECT語句translation1表即行的結果。

任何想法爲什麼在控制檯中它顯示它也從其他表中選擇,但實際上它總是從translation1表中獲取數據?

+0

強行清除會話緩存你在這些表中有相同的id字段值? – axtavt

+0

如果沒有在其他地方看到使用'rows',這個答案就不可能。例如,爲什麼'for'沒有在for循環中聲明? –

+0

@axtavt是所有表都有相同的id和相同的列名稱,除了一列rowText,它包含不同語言的文本,具體取決於轉換表。 – Rizwan

回答

2

如果所有表都具有相同的一組ID的,這是一個預期的行爲。

Hibernate會話緩存保證在會話中只能有一個特定類型實體的特定ID的實例。由於實體通過會話高速緩存解析,即使在本機查詢的情況下,您也會得到相同的實例。

所以,你有幾種選擇:

  • 重新考慮你的數據庫瑪從查詢結果
  • 構造對象手動
  • 致電clear()detach()
+0

感謝您的幫助,我無法更改db schema,entityManager.clear()修復了這個問題。 – Rizwan

+0

@ user908452:請注意,clear()會從會話緩存中刪除所有實體,如果這些實體中的某些實體被不同的方法加載,則可能會產生意想不到的副作用。也許最好使用'detach()'來顯式移除剛加載的實體。 – axtavt

0

您確定rows變量實際上並不包含返回結果的最後一個嗎?你如何初始化行,你如何處理循環中的變量?如果要從所有查詢中獲得所有結果,則必須將每個查詢(在循環內)添加到在循環開始之前聲明的列表/集變量。

或者你可以使用一些適當的SQL做:

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

我確定rows變量不包含最後的數據,我在循環之外初始化它 - 但我試圖在循環內部初始化它,但仍然無效。我遍歷行ArrayList並將其添加到地圖的地圖。 – Rizwan