使用jpa的時候set實(shí)體類屬性自動持久化的解決方案
使用jpa的時候set實(shí)體類屬性自動持久化
實(shí)例代碼
Set<User> users = new HashSet<User>();
User user = null;
for(int i = 0; i < 10; i++){
user = new User();
user.setUserName("wy" + i);
users.add(user);
}
Company company = userDao.getCompany();
company.setUsers(users);
當(dāng)使用了實(shí)體類set屬性的時候,但是我們并沒有持久化,卻自動保存到數(shù)據(jù)庫了。
原因
Hibernate分為三種基本的狀態(tài):游離態(tài)、自由態(tài)(臨時狀態(tài))、持久態(tài)。
持久化狀態(tài):與session關(guān)聯(lián)并且和在數(shù)據(jù)庫有數(shù)據(jù),已經(jīng)持久化了并且在數(shù)據(jù)庫的緩存當(dāng)中了。
我這里的這個對象應(yīng)該是持久化狀態(tài)的對象然后我直接構(gòu)造了一個user對象的set集合,同時對這個對象進(jìn)行set操作,那么緩存Session中的數(shù)據(jù)發(fā)生改變,那么接著數(shù)據(jù)庫也會跟著進(jìn)行相應(yīng)的改變。所以就執(zhí)行了update的更新操作。
解決辦法:
1.如果這個對象(例子中的company)本身不需要用的話,可以直接new一個Company的對象出來然后再setUsers這個時候因?yàn)椴皇荢ession中的數(shù)據(jù),那么不會因?yàn)閷ο蟮膶傩园l(fā)生改變而同步到數(shù)據(jù)庫中去。
2. 如果這個對象(例子中的company)要用的到,那么,在set之前可以先將其轉(zhuǎn)為游離態(tài),這樣的話會用到session的幾個方法:close、clear、evict。
close方法:關(guān)閉session這樣這個對象肯定是游離態(tài)了,因?yàn)閟ession已經(jīng)關(guān)閉了,但是往往我們實(shí)際的開發(fā)過程中,session在后面是要用的到的,所以這個方法可行,但是不一定用得上,分清具體的情況。
clear方法:將session中的所有的對象全部清除出緩存,這個方式有點(diǎn)勞師動眾,不過session清除了全部的對象之后自然就會變?yōu)橛坞x態(tài)了,這樣做不是很好吧我感覺。
evict方法:將某一個對象清除出緩存session,這個方法是很好的實(shí)現(xiàn)方式,推薦使用。調(diào)用的時候是這樣的,session.evict(Object obj);這樣就可以了。
使用注解獲取session方法
@PersistenceContext
private EntityManager entityManager;
然后在方式中我們使用如下方式獲取session
HibernateEntityManager hEntityManager = (HibernateEntityManager)entityManager;
Session session = hEntityManager.getSession();
然后使用獲取到的session根據(jù)上面說的操作對象既可
jpa實(shí)體類一對多set與list使用
當(dāng)從一的一端取出其所對應(yīng)的多的一端時,如果用的是set那么取出多的一端的值時順序是無序的,如果用的是list那么取出多的一端的值時順序是有序的(其實(shí)就是list與set的特性罷了,然鵝。。。。。。)
問題:因?yàn)閟et查詢出的數(shù)據(jù)是無序的,如果當(dāng)一的一端對應(yīng)5條數(shù)據(jù),而分頁的單頁只顯示3條數(shù)據(jù),當(dāng)?shù)较乱豁摃r,其中的兩條數(shù)據(jù)可能與與上一頁的3條數(shù)據(jù)出現(xiàn)隨機(jī)相同的情況,因此會導(dǎo)致數(shù)據(jù)顯示的缺失和無序。
注:不過jpa設(shè)計的時候用的是set不是沒有道理的,主要是利用set的數(shù)據(jù)不可重復(fù)性,用于避免數(shù)據(jù)的重復(fù),比如新增數(shù)據(jù)的時候避免數(shù)據(jù)的重復(fù)插入。
完美的解決辦法:
在實(shí)體類set屬性上加上@orderBy("id asc")屬性進(jìn)行排序,然后在取值的時候使用LinkedHashSet(不可重復(fù)且有序sss)接住即可
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot整合MyBatis逆向工程及 MyBatis通用Mapper實(shí)例詳解
這篇文章主要介紹了SpringBoot整合MyBatis逆向工程及 MyBatis通用Mapper實(shí)例詳解 ,需要的朋友可以參考下2017-09-09
Java使用泛型Class實(shí)現(xiàn)消除模板代碼
Class作為實(shí)現(xiàn)反射功能的類,在開發(fā)中經(jīng)常會用到,然而,當(dāng)Class遇上泛型后,事情就變得不是那么簡單了,所以本文就來講講Java如何使用泛型Class實(shí)現(xiàn)消除模板代碼,需要的可以參考一下2023-06-06
Spring Boot應(yīng)用程序同時支持HTTP和HTTPS協(xié)議的實(shí)現(xiàn)方法
如今,企業(yè)級應(yīng)用程序的常見場景是同時支持HTTP和HTTPS兩種協(xié)議,這篇文章考慮如何讓Spring Boot應(yīng)用程序同時支持HTTP和HTTPS兩種協(xié)議,需要的朋友可以參考下2019-10-10
Java 實(shí)戰(zhàn)范例之線上新聞平臺系統(tǒng)的實(shí)現(xiàn)
讀萬卷書不如行萬里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+jsp+jdbc+mysql實(shí)現(xiàn)一個線上新聞平臺系統(tǒng),大家可以在過程中查缺補(bǔ)漏,提升水平2021-11-11
springmvc實(shí)現(xiàn)跨服務(wù)器文件上傳功能
這篇文章主要為大家詳細(xì)介紹了springmvc實(shí)現(xiàn)跨服務(wù)器文件上傳功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-08-08
Spring Boot攔截器實(shí)現(xiàn)步驟及測試實(shí)例
這篇文章主要介紹了Spring Boot攔截器實(shí)現(xiàn)步驟及測試實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-04-04

