之前也遇到過一次這個問題姐霍,打印的日志中也可以看見update相關(guān)的sql語句心赶,但當(dāng)時不知道為什么會去自動更新珊泳,就用了別的方式去避免了。后來再次出現(xiàn)的時候猜极,用其他方式已經(jīng)無法避免中姜,還是要找到問題真正所在,發(fā)現(xiàn)是將從數(shù)據(jù)庫中獲取到的對象去set一個屬性的時候跟伏,數(shù)據(jù)庫就自動去update了
問題重述
//可退商品數(shù)量
orderGoods.setGoodsInfoNum(goodsNumSum);
//可退商品總價
orderGoods.setGoodsBackPrice(goodsPriceSum);
就類似上面的代碼丢胚,從數(shù)據(jù)庫中獲取到某個對象,然后在set屬性時更新了數(shù)據(jù)庫受扳,在控制臺可以看到打印的相應(yīng)更新的語句
問題原因
Hibernate有三種基本狀態(tài):
自由態(tài)(臨時狀態(tài)):直接new出來的對象携龟,既沒有被保存到數(shù)據(jù)庫中,也不處于session緩存中
游離態(tài):已經(jīng)被保存到數(shù)據(jù)庫中但不處于session緩存中
持久態(tài):已經(jīng)被保存到數(shù)據(jù)庫中并且加入到session緩存中
上述代碼中的對象是持久化狀態(tài)的對象勘高,對其進(jìn)行set操作時session緩存中的數(shù)據(jù)發(fā)生了改變峡蟋,數(shù)據(jù)庫也會跟著進(jìn)行相應(yīng)的改變,所以執(zhí)行了update的更新操作
問題解決
OrderGoods orderGoodsCopy = new OrderGoods();
BeanUtils.copyProperties(orderGoods,orderGoodsCopy);
//可退商品數(shù)量
orderGoodsCopy.setGoodsInfoNum(goodsNumSum);
//可退商品總價
orderGoodsCopy.setGoodsBackPrice(goodsPriceSum);
最簡單也是最容易想到的方式就是重新new一個對象然后再去set屬性华望,這個時候因為不是session中的數(shù)據(jù)蕊蝗,不會因為對象屬性發(fā)生改變而同步到數(shù)據(jù)庫中
但如果這個對象要用的到,那么在set之前可以先將其轉(zhuǎn)為游離態(tài)赖舟,session中提供了幾個方法:
close方法:關(guān)閉session這樣這個對象肯定是游離態(tài)了,因為session已經(jīng)關(guān)閉了,但是往往我們實際的開發(fā)過程中磁餐,session在后面是要用的到的树叽,所以這個方法雖然可行,但也要分場景
clear方法:將session中的所有的對象全部清除出緩存石洗,雖然session清除了全部的對象之后自然就會變?yōu)橛坞x態(tài)了幢泼,但這樣做不太合適
evict方法:將某一個對象清除出緩存session,這個方法是很好的實現(xiàn)方式劲腿,推薦使用