解決JPA查詢到的對象屬性被set后,自動執行update


問題描述

做項目開發的時候遇到這樣一個問題:更新數據庫某一記錄的時候,先從數據庫中查詢到這個紀錄,然后set修改數據項,當某個字段set和查詢出來的不一致的時候,看到控制台打印的SQL日志顯示執行了Update操作,很納悶,查看代碼,只是一個簡單的set操作啊,數據庫怎么會被更新?
查看資料后才知道,使用JPA查詢后的對象處於持久態,持久態的對象屬性在被set后,會自動執行update語句更新數據庫。
這才恍然大悟,基於這個原因,只要把持久態的對象轉換為游離態或者是臨時態,就可以解決問題。
先理解下Hibernate 中對象的三種狀態:

  1. 臨時狀態:通過new新建的對象,沒有被持久化,也不在session緩存中

  2. 游離狀態:已經被持久化,但不在session緩存中

  3. 持久狀態:已經被持久化,也在session緩存中

(持久化:數據庫有這條數據)
持久態到游離態的方法有:session.close()、session.evict(obj)、session.clear()

  1. close():關閉session,整個session中的持久態對象都成為游離態
  2. clear():清楚session中的所有緩存,所有持久化對象變為游離態
  3. evict(obj):把某個持久化狀態的對象從session中清除,該對象變為游離態,推薦用此方法

解決方案

  1. 隔離Entity:new一個對象,把查詢出來的對象通過BeanUtils.copyProperties賦值給new出來的對象,更新操作使用new之后的對象

  2. 把持久化狀態的obj從session中清除

    1. 首先引入EntityManager
    @PersistenceContext
    private EntityManager entityManager;
    
    1. 把obj從session中清除
    HibernateEntityManager hibernateEntityManager = (HibernateEntityManager) entityManager;
    Session session = hibernateEntityManager.getSession();
    session.evict(obj);
    

總結

出現這種現象的前提,查詢以及對查詢后的實體set值都必須在一個事務里,並且在方法執行結束,事務提交前,不管有沒有顯示調用Update,JPA都會自動調用Update


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM