Spring Data JPA 的 @Modifying 注解需要注意的問題

[每日短篇] 19 - Spring Data JPA 的 @Modifying 注解需要注意的問題?

JPA 的 Repository 提供一種非常易用的機制用于 ORM 方式處理數(shù)據(jù)十籍,但是如果需要一次性更新一批數(shù)據(jù)的部分字段别垮,構(gòu)造所有實體并逐個修改字段再存回數(shù)據(jù)庫就顯得有些臃腫。在 JPA 中提供了?@Query?注解用于使用 JPQL 執(zhí)行數(shù)據(jù)庫操作椒袍,如果數(shù)據(jù)庫操作是修改數(shù)據(jù)而非查詢數(shù)據(jù)藕施,則需要再額外使用?@Modifying?注解提示 JPA 該操作是修改操作寇损。

當(dāng)進行 find 操作時,JPA 在 EntityManager 中緩存了 find 生成的對象铅碍,當(dāng)再次 find 時會直接返回該對象琢融。于是可能會出現(xiàn)下面這種情況 用?@Query?定義一個修改狀態(tài)的方法

public interface EntityRepository extends JpaRepository {

????@Modifying

????@Query("update Entity set status = 'IGNORED' where id = ?1")

? ? intupdateStatus(intid);

}

先讀取一個對象老充,再修改對象狀態(tài),再次讀取對象

Optional entityBefore = repository.findById(1);

repository.updateStatus(1);

Optional entityAfter = repository.findById(1);

結(jié)果會發(fā)現(xiàn) entityBefore 和 entityAfter 中的 Entity 對象 id 是相同的肖油,中間對狀態(tài)的修改并沒有體現(xiàn)出來憨愉!當(dāng)然烦绳,其原因也很明確,@Query?跟 find 和 save 系列方法是兩套不同的體系配紫,@Query?引起的數(shù)據(jù)庫變更 EntityManager 并不能發(fā)現(xiàn)径密,更進一步說,使用其它工具或者其它框架修改數(shù)據(jù)庫中的數(shù)據(jù)躺孝,也不能及時反應(yīng)到 JPA 的 find 系列方法上來享扔。

當(dāng)然底桂,只要有緩存機制就一定不可避免存在此類問題,這僅是個取舍問題而不要認(rèn)為是 BUG惧眠。如果要解決 find 得到的值不是數(shù)據(jù)庫中最新值的問題可以有幾種方式籽懦,避免使用?@Query?是一種方式,在需要時顯式清理 EntityManager 的緩存也是一種方式氛魁。Spring Data JPA 提供了另外一種方式則是?@Modifying(clearAutomatically = true)暮顺,@Modifying?的 clearAutomatically 屬性為 true 時,執(zhí)行完 modifying query 之后就會清理緩存秀存,從而在下次 find 時就可以讀取到數(shù)據(jù)庫中的最新值捶码。

自動清理之后還會帶來一個新的問題,clear 操作清理的緩存中或链,還包括提交后未 flush 的數(shù)據(jù)惫恼,例如調(diào)用 save 而不是 saveAndFlush 就有可能不會立即將修改內(nèi)容更新到數(shù)據(jù)庫中,在 save 之后 flush 之前調(diào)用?@Modifying(clearAutomatically = true)?修飾的方法就有可能導(dǎo)致修改丟失株扛。如果再要解決這個問題尤筐,還可以再加上另外一個屬性?@Modifying(clearAutomatically = true, flushAutomatically = true),@Modifying?的 flushAutomatically 屬性為 true 時洞就,執(zhí)行 modifying query 之前會先調(diào)用 flush 操作盆繁,從而避免數(shù)據(jù)丟失問題。

在實際運行中旬蟋,clear 和 flush 操作都可能需要消耗一定的時間油昂,要根據(jù)系統(tǒng)實際情況可以選擇使用其中的一個或兩個屬性,以保證系統(tǒng)的正確性倾贰。

參考: flushAutomatically 屬性是在?https://jira.spring.io/browse/DATAJPA-806?提出并被采納的冕碟。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市匆浙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌首尼,老刑警劉巖挑庶,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異软能,居然都是意外死亡,警方通過查閱死者的電腦和手機凳枝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進店門岖瑰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來叛买,“玉大人,你說我怎么就攤上這事锭环〈先” “怎么了?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵辅辩,是天一觀的道長难礼。 經(jīng)常有香客問我,道長玫锋,這世上最難降的妖魔是什么蛾茉? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮撩鹿,結(jié)果婚禮上谦炬,老公的妹妹穿的比我還像新娘。我一直安慰自己节沦,他們只是感情好键思,可當(dāng)我...
    茶點故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著甫贯,像睡著了一般吼鳞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上叫搁,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天赔桌,我揣著相機與錄音,去河邊找鬼渴逻。 笑死疾党,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的惨奕。 我是一名探鬼主播雪位,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼梨撞!你這毒婦竟也來了雹洗?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤聋袋,失蹤者是張志新(化名)和其女友劉穎队伟,沒想到半個月后穴吹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體幽勒,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年港令,在試婚紗的時候發(fā)現(xiàn)自己被綠了啥容。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片锈颗。...
    茶點故事閱讀 39,932評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖咪惠,靈堂內(nèi)的尸體忽然破棺而出击吱,到底是詐尸還是另有隱情,我是刑警寧澤遥昧,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布覆醇,位于F島的核電站,受9級特大地震影響炭臭,放射性物質(zhì)發(fā)生泄漏永脓。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一鞋仍、第九天 我趴在偏房一處隱蔽的房頂上張望常摧。 院中可真熱鬧,春花似錦威创、人聲如沸落午。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽溃斋。三九已至,卻和暖如春详炬,著一層夾襖步出監(jiān)牢的瞬間盐类,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工呛谜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留在跳,地道東北人。 一個月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓隐岛,卻偏偏與公主長得像猫妙,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子聚凹,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,884評論 2 354