關於SpringDataJpa使用@Queue自定義查詢語句的坑

今天遇到一個坑,很是奇葩,做個記錄,也希望可以幫到大家,或者哪位大佬指出問題錯在。

問題描述:Jpa中使用@Queue註解進行update操作,感覺沒有命中數據庫,返回值始終不正確

解決方案:使用findById搭配save進行更新語句---->也就是先查詢,後修改

 

如果有興趣的,可以繼續往下看

 

第一部分:數據庫運行,試水

這裏可以看到我們運行 update my_order set is_dispose = 1 where id = 14805531574272 這條Sql語句的影響行數是 0

因爲我們之前就已經運行過這條Sql語句了,此時的數據庫的字段is_dispose已經是1了,所以影響的行數是0

--------> 試水成功

 

第二部分:創建本地接口

那麼接下來我創建了一個接口,就是用於修改是否處理的,如下:


    @Modifying(flushAutomatically = true,clearAutomatically = true)
    @Query(value = "update my_order set is_dispose = 1 where id = ?1",nativeQuery = true)
    Integer updMyOrderById(@Param("id")Long id);

我先介紹一下這幾個註解:

@Modifying(flushAutomatically = true,clearAutomatically = true)

@Modifying:Jpa使用@Queue的時候需要加上該註解

   flushAutomatically:表示在執行@Queue中的語句的時候(也就是更新或者刪除)會刷新該對應的實體類(應該會去查詢)

   clearAutomatically:這個就是表示在執行以後會刷新

nativeQuery = true:表示本地執行Sql語句,也就是說是原生的Sql語句,就相當於是把我們寫的sql語句複製到數據庫跑

 

第三部分:Debug運行

如圖,可以看到我們使用的ID還是用一個ID,也就是14805531574272 但是我們受影響的行數居然赫然是1     那這樣不行啊,這會影響到程序的結果的,那這樣我們就不會拋出異常,程序就不會回滾,這是一個很嚴肅的事情

這是怎麼回事呢?說實話我現在都還不知道,所以只好開啓百度模式,於是我發現了另外兩個註解:

@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@DynamicInsert   // ----> 就是這兩個
@DynamicUpdate   // ----> 就是這兩個
public class MyOrder {

那麼這兩個註解是幹嘛的?

@DynamicInsert :表示會在執行Insert的時候創建一個動態的sql語句,也就是說只要是數據是null的就不會添加到Sql語句中
@DynamicUpdate :同理,就是在Update的時候如果是null也不會添加到Sql語句中

還別說哈,問題沒解決,又發現了新大陸呢。

 

所以到現在我還沒發現是怎麼回事?那隻好另闢蹊徑換一種方式進行update

第四部分:使用save搭配findById進行更新語句

    @Override
    @Transactional
    public List<Jackpot> saveAllJackpot(List<Jackpot> jackpots, Long id) {
        List<Jackpot> newJackpots = jackpotRepo.saveAll(jackpots);
        Assert.notEmpty(newJackpots, "綁定多條獎項失敗");
        MyOrder myOrder = myOrderRepo.findById(id).get();
        if (myOrder.getIsDispose()) {
            throw new IllegalArgumentException("訂單已處理");
        }
        myOrder.setIsDispose(true);
        MyOrder save = myOrderRepo.save(myOrder);
        Assert.notNull(save, "更新訂單狀態失敗");
        return newJackpots;
    }

對的,就是採用這種笨拙的方式進行更新,首先我們在更新之前先根據id查詢出來該對象信息。然後進行判斷對象信息,如果對象的isDispose爲true那就代表這個訂單已經被處理了,那麼就不會執行後面的save更新語句,如果不是true就代表還沒處理該訂單,那麼我們就把狀態賦值爲true,在執行save修改訂單,這樣就達到了我的業務需求。

 

結語:到這裏基本上就結束了,在這裏謝謝大家花費寶貴的時間點開這篇文章並且看到了這裏,目前針對之所以出現上訴問題,個人感覺是我使用@Queue執行Update語句的時候沒有命中數據庫,所以每次都會出現返回值不正確的原因,至於爲啥會出這個爲題的原因我也不清楚,我也還只是個Jpa的小白,我甚至hibernate都沒有學習過,如果有哪位大佬路過,歡迎評論區指出~~

 

~~~謝謝大家的觀看

 

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