Spring Data JPA坑點記錄

2021-08-13 21:51:47 字數 2909 閱讀 4070

場景:動態查詢,分頁查詢,根據傳入不同的狀態,分別查詢不同資料表,並且在傳入page物件之前用map進行vo轉換。而pageable的使用地方不同影響到了分頁資料的正確性,以此進行**。

前提:page物件封於vo內,返回資料報括了分頁資料

@apimodelproperty("記錄")

private pageactivityrecordvolist;

@apimodelproperty("數量")

private integer num = 0;

@apimodelproperty("金額")

private bigdecimal totalmoney = bigdecimal.valueof(0);

錯誤運用:

listactivityrecordvolist = new arraylist<>();

if (receivesendrecordrequestvo.getsendorreceivetype() == sendorreceivetype.receive)

} else if (receivesendrecordrequestvo.getsendorreceivetype() == sendorreceivetype.send)

}

activityreceivesendrecordvo.setactivityrecordvolist(new pageimpl<>(activityrecordvolist,

pageable, activityrecordvolist.size()));

解析:傳入的pageable只在set進vo的時候,用new pageiml將list轉為page物件,前端報的問題雖然總頁數、總條數均為正確,但第一頁的條數是全部,資料異常!

採用specifications先根據查詢條件動態查詢並map出相應分頁物件(此塊**因需求而異),這時findall傳入的pageable是生效的,便會顯現正確的分頁資訊。

**塊參考:

***commonspecutil是自封的specification工具類,與原生spring data jpa原生查詢方法類似。

pagepage = new pageimpl<>(activityrecordvolist, pageable, activityrecordvolist.size());

if (receivesendrecordrequestvo.getsendorreceivetype() == sendorreceivetype.receive) else if (receivesendrecordrequestvo.getsendorreceivetype() == sendorreceivetype.send)

注:activityreceivesendrecordvo為封裝的vo,包含了返回的page物件

activityreceivesendrecordvo.setactivityrecordvolist(page);
場景:@transactional事務,更新使用者餘額(處理併發問題),更新完畢返回vo帶上使用者剩餘餘額,但卻非更新後的餘額。

更新邏輯**:

userwebservice.updatebalanceaftertransaction(userid, transactionrecordaddvo.getmoney(),user.getbalance());
@transactional

public void updatebalanceaftertransaction(integer userid, bigdecimal money, bigdecimal userbalance)

}

@modifying

@query(value = "update user u set u.balance = u.balance - ?2 where u.id = ?1 and u.balance = ?3")

int updatebalanceaftertransaction(integer userid, bigdecimal money, bigdecimal userbalance);

解析:

在jpa中使用@modifying,雖然事務已經能夠更新,但是在迴圈更新的時候,執行modify語句後的查詢的實體仍然是沒有更新的。

執行完modifying query, entitymanager可能會包含過時的資料,因為entitymanager不會自動清除實體。

只有新增clearautomatically屬性,entitymanager才會自動清除實體物件。

新增**:

@modifying(clearautomatically = true)
改正後的示例**:

@modifying(clearautomatically = true)

@query(value = "update user u set u.balance = u.balance - ?2 where u.id = ?1 and u.balance = ?3")

int updatebalanceaftertransaction(integer userid, bigdecimal money, bigdecimal userbalance);

使用了這麼長時間spring data jpa,覺得specifications巨好用,也不容易出錯,也是我喜歡的編碼風格,而new pageimpl<>()這種簡單粗暴的方法我一般都用在查詢資料關聯太多表的情況,在最後直接返回,更深層次的還需要再**!

spring data jpa遇到的坑

1 column註解name最好全寫了,不然遇到像hibernate駝峰和下劃線風格配置變更時會出現找不到屬性,尤其開啟自動建表情況 2 唯讀操作情況,如果對讀取物件進行了屬性修改操作,那麼jpa會認為你要修改這個實體,使用hibernate的情況下回預設執行乙個update的sql,然後你懂得由於...

spring data jpa實體繼承

spring jpa中我們要將sql對映到物件,尤其是在spring boot這種高度自動化的環境下使用,大量的最優目錄結構與命名規則可以大大降低配置,約定大於配置貫穿其中。例如我們定義查詢dao,繼承jparepository即可。然後返回的物件,我們可以定義model entity table ...

SpringData JPA分頁查詢

首先我們需要知道springdata jpa 的幾個介面 其實看名字就大概懂了,也可以很方便的使用 首先我們的持久化層繼承jparepository,相當於繼承了增刪改查的持久化層以及分頁查詢的持久化層 所以如果我們要使用分頁查詢 我們只需要直接呼叫 由一開始的圖也可以看到pageable的其中乙個...