spingBoot中spring data jpa的一次查詢問題解決

spingBoot中spring data jpa的一次查詢問題解決

這個問題令我真的是印象深刻。現在記錄一下該問題的詳細解決過程,解決問題的思路很重要。

1.問題描述:

一個簡單的查詢,根據某字段查詢值,實體類是一個視圖。
dao:

    @Query(value="from ViewGxxx  where num = ?1")
    VietEntity findByunt1(String ccount);

查詢:

     ViewDebtEntity en1 = viewDao.findByAccount1(dkzhList.get(1));
     ViewDebtEntity en2 = viewDao.findByAccount1(dkzhList.get(0));
    ViewDebtEntity  en3 = viewDao.findBytAccount1("021001055215000000790");

三個查詢條件是不相同的。
查詢結果以及現象如下:

  1. 所有的值都相同,en1 = en2 = en3
  2. 比如第一次查的結果爲“xxx” , 那之後多次查詢的結果都爲“xxx” ,儘管查詢條件都不一樣。

2.問題解決

開始用的是 根據方法名查詢的 如 findbyxxxIn(List) , 就是參數是一個list , 批量查詢,
出現問題後,以爲是方法的問題,後來就改爲上述的直接用jpql 語句查詢。然後問題依舊存在。

  • debug調試,查看查詢方法的輸入參數,確實不一樣。
  • 用上述幾個不同的參數去數據庫寫sql 查詢,確實能查到不同的數據。
  • 改變日誌數據,查看spring data jpa 發送的sql 打印,看到三次打印的sql , 一模一樣但是參數卻是個 “?” 。
  • 改變日誌輸出配置,讓sql 的參數也顯示出來。具體做法
  • sql 參數也打印了出來,結果發現,發送的sql的參數也的確是不同的。

進行到這裏就真的感到這個問題妖異的很了。

接下來進行進一步分析。

什麼原因能導致這樣的現象呢, 想想看,同樣的sql 語句,不同的參數,查詢出來的結果都一樣,並且都等於第一次查詢的。
那就難免想到緩存的東西了,問題是這種緩存明顯是不合邏輯也不合常理的。

最後去看了實例類(orm 數據裏邊是view)

在這裏插入圖片描述
注意這裏將id 視爲主鍵 (邏輯上不允許重複的)

然後去數據庫一探究竟:
在這裏插入圖片描述

看到一個id的字段,值卻都是相同的. 這…

然後帶着這個證據去分析上述的問題:

  1. 我是將id屬性用@Id 作爲主鍵, 那麼 sping data jpa 就認爲id 屬性是唯一的.
  2. 然後我進行第一次查詢,得到 en1, 得到的結果爲 xxx (id 爲1) sping data jpa 底層實現用的hibernate 發送sql 進行查詢,.
  3. 然後進行第二次查詢,然後發送sql , 數據庫的索引機制,查找普通字段,會先找到對應id , 然後,有id ,查詢對應的整個記錄. 由於 第二次查詢雖然用的不同條件,但是對應的id相同,於是從緩存中返回了上次相同id的查詢結果.

因此這個視圖的數據是有問題的了,id 都一樣, 爲了證實這一點,我再視圖裏邊找了一個唯一的字段,響應的在其上邊加上@Id註解, 再進行查詢得到的結果就是不同的了.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章