PS:禁止拷貝形式轉(zhuǎn)載,轉(zhuǎn)載請以URL形式
1.簡介
解決JPA/hibernate 實體多對多關(guān)系下,操作實體無法直接級聯(lián)刪除中間表,報錯。
2.環(huán)境
- jdk1.8
- springboot:2.2.8.RELEASE
3.解決思路
-
正常多對多
- 實體A使用多對多關(guān)聯(lián)(@ManyToMany)關(guān)聯(lián)B,JPA自動生成第三張中間表C,
- 然后在需要刪除實體并且級聯(lián)刪除中間表時,提前刪除中間表C的關(guān)聯(lián)數(shù)據(jù)。
-
雙向一對多
- 實體A使用雙向一對多(@OneToMany)關(guān)聯(lián)C,并且設(shè)置C為維護方;
- 實體B使用雙向一對多(@OneToMany)關(guān)聯(lián)C,并且設(shè)置C為維護方;
- 通過JPA任意刪除A/B都會刪除中間表數(shù)據(jù)C,而不會刪除另一方
4.代碼
4.1 雙向一對多實現(xiàn)
實體A
@Data
@Entity
@Table(name = "tb_a")
public class TbA {
@Id
@Column(name = "c_uuid", unique = true, length = 36, nullable = false)
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "org.hibernate.id.UUIDGenerator")
private String uuid;
@OneToMany(cascade = {CascadeType.ALL},mappedBy = "a")
private List<TbC> cList;
}
實體B
@Data
@Entity
@Table(name = "tb_b")
public class TbB {
@Id
@Column(name = "c_uuid", unique = true, length = 36, nullable = false)
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "org.hibernate.id.UUIDGenerator")
private String uuid;
@OneToMany(cascade = {CascadeType.ALL},mappedBy = "b")
private List<TbC> cList;
}
中間表C
@Data
@Entity
@Table(name = "tb_c")
@IdClass(TbC.TbCEmbeddable.class)
public class TbC {
@Id
@ManyToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH})
@JoinColumn(name = "c_a_foreign_key")
private TbA a;
@Id
@ManyToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH})
@JoinColumn(name = "c_b_foreign_key")
private TbA b;
@Data
public static class TbCEmbeddable implements Serializable {
private TbA a;
private TbB b;
}
}
級聯(lián)刪除代碼
@NoRepositoryBean
public interface BaseDao<T,ID extends Serializable> extends JpaRepository<T,ID> , JpaSpecificationExecutor<T> {
//RestResource
}
BaseDao<TbCollectManageItem,String> dao = factory.getDao(TbCollectManageItem.class);
dao.deleteById(uuid);