欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

jpa?onetomany?使用級(jí)連表刪除被維護(hù)表數(shù)據(jù)時(shí)的坑

 更新時(shí)間:2021年12月06日 09:31:29   作者:Jimi1985  
這篇文章主要介紹了jpa?onetomany?使用級(jí)連表刪除被維護(hù)表數(shù)據(jù)時(shí)的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

jpa onetomany 使用級(jí)連表刪除被維護(hù)表數(shù)據(jù)時(shí)的坑

一、異常產(chǎn)生的場(chǎng)景

兩個(gè)實(shí)體類,為一對(duì)多的關(guān)系

主表 ,字段維護(hù)表,1個(gè)用戶可能有多個(gè)角色

實(shí)體類User,代碼如下:

package ywcai.ls.entity;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
@Entity
@Table(name="user")
public class User implements Serializable{
/**
* 
*/
private static final long serialVersionUID = -7383132326629943397L;
@Id
    @GeneratedValue(strategy= GenerationType.AUTO)
    @Column(name="id")
    private Long id;
    @Column(name="username")
    private String username;
    @Column(name="password")
    private String password;
    @OneToMany(cascade={CascadeType.ALL},fetch=FetchType.EAGER,mappedBy="user")
   //特別注意:onetomany標(biāo)識(shí)這是級(jí)聯(lián)1對(duì)多的關(guān)系。cascade={CascadeType.ALL}表示主表的增查刪改都會(huì)直接通過(guò)關(guān)聯(lián)字段對(duì)從表進(jìn)行相應(yīng)操作。
   //例如刪除主表的一個(gè)user實(shí)例,從表與user相關(guān)聯(lián)roles將被刪除。
   //而fetch=FetchType.EAGER表示急加載,即指一旦主表進(jìn)行了相應(yīng)操作,則從表也將立即進(jìn)行相應(yīng)的級(jí)聯(lián)操作。
   //例如,一旦讀取了user表的某一個(gè)實(shí)例,則user會(huì)立即加載Roles;而fetch=FetchType.LAZY為懶加載,當(dāng)需要使用到getRolelist()方法時(shí),才會(huì)讀取相關(guān)聯(lián)的級(jí)聯(lián)表數(shù)據(jù)
    @OrderBy(value= "id ASC")//獲取的角色信息根據(jù)角色表的id進(jìn)行升序排序
    private Set<Roles> rolelist;
    
public Set<Roles> getRolelist() {
return rolelist;
}
public void setRolelist(Set<Roles> rolelist) {
this.rolelist = rolelist;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
}

被維護(hù)的級(jí)聯(lián)表,多個(gè)Roles角色可能對(duì)應(yīng)1個(gè)用戶

實(shí)體類Roles,代碼如下:

package ywcai.ls.entity;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name="roles")
public class Roles {
    @Id
    @GeneratedValue(strategy= GenerationType.AUTO)
    @Column(name="id")
    private Long id;
    @Column(name="username")
    private String username;
    @Column(name="rolename")
    private String rolename;
    @ManyToOne(cascade={CascadeType.REFRESH},fetch=FetchType.LAZY)
    @JoinColumn(name="userid")//加入一列作為外鍵
    private User user;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getRolename() {
return rolename;
}
public void setRolename(String rolename) {
this.rolename = rolename;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}

二、存在異常的問(wèn)題

當(dāng)Roles類級(jí)聯(lián)操作屬性使用(cascade={CascadeType.REFRESH},這樣主要為達(dá)到對(duì)從表的某一個(gè)用戶的權(quán)限進(jìn)行操作,而不影響主表User。

這時(shí)候Roles的注解

@ManyToOne(cascade={CascadeType.REFRESH},fetch=FetchType.EAGER)

通過(guò)user對(duì)Roles進(jìn)行增加操作時(shí),無(wú)任何問(wèn)題。但單獨(dú)對(duì)Roles表中的一項(xiàng)進(jìn)行刪除,例如單獨(dú)刪除A用戶的管理員橘色,則無(wú)法刪除。

@Repository
@Table(name="roles")
@Qualifier("rolesRepository")
public interface RolesRepository extends JpaRepository<Roles, Long > {
@Transactional
int deleteByUsernameAndRolename(String username,String rolename);
}

首先通過(guò)JpaRepository約束接口刪除數(shù)據(jù),必須開啟事務(wù),否則報(bào)錯(cuò)。

而開啟事務(wù)后,該刪除代碼可以執(zhí)行,執(zhí)行返回的結(jié)果也正常返回1,但實(shí)際的數(shù)據(jù)中卻沒(méi)有反應(yīng),數(shù)據(jù)無(wú)法被刪除。

三、異常原因分析

出現(xiàn)該問(wèn)題的原因是Roles使用了CascadeType.REFRESH注解,Roles刪除了該表中的相應(yīng)數(shù)據(jù)后,會(huì)自動(dòng)試圖去刪除主表中該USER實(shí)體數(shù)據(jù)。但由于注解中僅賦予了CascadeType.REFRESH,讀取刷新數(shù)據(jù)的權(quán)限,因此刪除主表中該USER實(shí)體數(shù)據(jù)的語(yǔ)句是無(wú)法執(zhí)行的,最終造成了整個(gè)deleteByUsernameAndRolename()事務(wù)的失敗回滾,結(jié)果就是要?jiǎng)h的數(shù)據(jù)沒(méi)刪掉。

若在Roles實(shí)體類增加CascadeType.REMOVE權(quán)限,雖deleteByUsernameAndRolename()的事務(wù)可以正常執(zhí)行,但會(huì)造成主表USER用戶也被整體刪除,進(jìn)而反過(guò)來(lái)造成Roles表中所有該USER的角色也都被刪除。顯然,這和業(yè)務(wù)需求也不符合。

四、解決方案

上訴的問(wèn)題看起來(lái)已經(jīng)是一個(gè)邏輯相悖的矛盾,無(wú)法解決。實(shí)際上只需要將Roles中加載模式改為懶加載即可,User實(shí)體類的加載模式不需改變。

當(dāng)刪除roles中記錄時(shí)不會(huì)立即觸發(fā)到對(duì)User實(shí)體類數(shù)據(jù)的刪除,也就不會(huì)報(bào)錯(cuò)和造成失誤的回滾。

jpa onetomany的用法

one部分

時(shí)機(jī)項(xiàng)目中使用到的。

@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY,mappedBy="dcpDataServiceManage")
    private List<DcpDataServiceTableFieldEntity> dataServiceTableFieldList;

注意這個(gè)mappBy 要和many部分字段對(duì)應(yīng)上

many部分

/**
     * 關(guān)聯(lián)的
     */
    @ManyToOne
    @JoinColumn(referencedColumnName = "gid")
    private DcpDataServiceManageEntity dcpDataServiceManage;

這塊注意的是數(shù)據(jù)庫(kù)保存的是實(shí)體類的gid.。one部分mappBy就是這個(gè)字段名。

注意

這塊就可以省去中間的一張關(guān)聯(lián)表。由于項(xiàng)目的原因。不能采用jpa 自動(dòng)建表的功能。這里使用的是sql。 特別注意的是這個(gè)字段名在數(shù)據(jù)庫(kù)創(chuàng)建的時(shí)候要加GID的

在這里插入圖片描述

像上面代碼塊的字段 根據(jù)表映射規(guī)則 數(shù)據(jù)庫(kù)存的字段應(yīng)該是DCP_DATA_SERVICE_MANAGE_GID 這個(gè)要注意一下

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 一場(chǎng)由Java中Integer引發(fā)的踩坑實(shí)戰(zhàn)

    一場(chǎng)由Java中Integer引發(fā)的踩坑實(shí)戰(zhàn)

    Java中的數(shù)據(jù)類型分為基本數(shù)據(jù)類型和復(fù)雜數(shù)據(jù)類型int是前者而integer是后者(也就是一個(gè)類),下面這篇文章主要給大家介紹了關(guān)于由Java中Integer引發(fā)的踩坑實(shí)戰(zhàn),需要的朋友可以參考下
    2022-11-11
  • Spring boot外部配置(配置中心化)詳解

    Spring boot外部配置(配置中心化)詳解

    這篇文章主要給大家介紹了關(guān)于Spring boot外部配置(配置中心化)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-12-12
  • GateWay動(dòng)態(tài)路由與負(fù)載均衡詳細(xì)介紹

    GateWay動(dòng)態(tài)路由與負(fù)載均衡詳細(xì)介紹

    這篇文章主要介紹了GateWay動(dòng)態(tài)路由與負(fù)載均衡,GateWay支持自動(dòng)從注冊(cè)中心中獲取服務(wù)列表并訪問(wèn),即所謂的動(dòng)態(tài)路由
    2022-11-11
  • Java判斷線程池線程是否執(zhí)行完畢

    Java判斷線程池線程是否執(zhí)行完畢

    這篇文章主要介紹了Java判斷線程池線程是否執(zhí)行完畢,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • Java基礎(chǔ)之this關(guān)鍵字的使用

    Java基礎(chǔ)之this關(guān)鍵字的使用

    今天給大家?guī)?lái)的是關(guān)于Java基礎(chǔ)的相關(guān)知識(shí),文章圍繞著this關(guān)鍵字的使用展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • springboot項(xiàng)目攔截器重定向循環(huán)問(wèn)題的解決

    springboot項(xiàng)目攔截器重定向循環(huán)問(wèn)題的解決

    這篇文章主要介紹了springboot項(xiàng)目攔截器重定向循環(huán)問(wèn)題的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • 帶你了解Java數(shù)據(jù)結(jié)構(gòu)和算法之二叉樹

    帶你了解Java數(shù)據(jù)結(jié)構(gòu)和算法之二叉樹

    這篇文章主要為大家介紹了Java數(shù)據(jù)結(jié)構(gòu)和算法之二叉樹,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-01-01
  • Java面向?qū)ο笾^承、構(gòu)造方法、重寫、重載

    Java面向?qū)ο笾^承、構(gòu)造方法、重寫、重載

    本章具體介紹了什么是構(gòu)造方法、繼承、重寫、重載以及創(chuàng)建方法,整篇文章用老司機(jī)和人類來(lái)舉例,圖解穿插代碼案例,需要的朋友可以參考下
    2023-03-03
  • 打開.properties中文顯示unicode編碼問(wèn)題以及解決

    打開.properties中文顯示unicode編碼問(wèn)題以及解決

    這篇文章主要介紹了打開.properties中文顯示unicode編碼問(wèn)題以及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Springboot啟動(dòng)擴(kuò)展點(diǎn)超詳細(xì)教程小結(jié)

    Springboot啟動(dòng)擴(kuò)展點(diǎn)超詳細(xì)教程小結(jié)

    這篇文章主要介紹了Springboot啟動(dòng)擴(kuò)展點(diǎn)超詳細(xì)教程小結(jié),本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07

最新評(píng)論