JPA插入時出現(save the transient before flushing) 解決辦法
阿新 • • 發佈:2021-01-20
情景分析:
出現bug的時候,是由於用jpa對兩個實體類進行了關聯,例如:Customer類和LinkMan類兩個類,Customer類中引入了LinkMan類(即關聯了某些欄位)這個時候如果我們不設級聯cascade為all的話,就會報錯,但是級聯為all又會出現其他問題,這個時候我們就可以進行手動儲存,先儲存Customer類,再呼叫LinkMan類的set方法,最後進行對LinkMan類的儲存.
User類:
package com.linyh.entity; import lombok.*; import javax.persistence.*; import java.util.HashSet;import java.util.Set; @Entity @Table(name = "cst_customer") @Data @AllArgsConstructor @NoArgsConstructor public class Customer { /** * @ Id宣告主鍵的設定 * @ GeneratedValue配置主鍵是生成策略(自動增長) * GenerationType.IDENTITY * @ Column(name = "cust_id")資料庫中表中欄位的名字 */ @Id @GeneratedValue(strategy= GenerationType.IDENTITY) @Column(name = "cust_id") private Long custId; @Column(name = "cust_name") private String custName; @Column(name = "cust_source") private String custSource; @Column(name = "cust_industry") private String custIndustry; @Column(name = "cust_level")private String custLevel; @Column(name = "cust_address") private String custAddress; @Column(name = "cust_phone") private String custPhone; /** * 配置客戶與聯絡人之間的關係(一個客戶對應多個聯絡人) * 使用註解的形式配置多表關係 * 1 宣告關係 * @ OnetoMany:配置一對多關係 * targetEntity:對方物件的位元組碼物件 * 2.配置外來鍵(中間表) * @ JoinColumn * name:外來鍵的在從表的欄位名稱(不是屬性,是資料庫的欄位名稱) * referencedColumnName:參照的主表的欄位名稱 */ @OneToMany(targetEntity = LinkMan.class) @JoinColumn(name = "lkm_cust_id", referencedColumnName = "cust_id") private Set<LinkMan> linkManSet = new HashSet<>(); }
預設無級聯:
LinkMan類:
package com.linyh.entity; import lombok.*; import javax.persistence.*; import java.util.Map; @Entity @Table(name="cst_linkman") @Data @AllArgsConstructor @NoArgsConstructor public class LinkMan { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "lkm_id") private Long lkmId; @Column(name = "lkm_name") private String lkmName; @Column(name = "lkm_gender") private String lkmGender; @Column(name = "lkm_phone") private String lkmPhone; @Column(name = "lkm_mobile") private String lkmMobile; @Column(name = "lkm_email") private String lkmEmail; @Column(name = "lkm_position") private String lkmPosition; @Column(name = "lkm_memo") private String lkmMemo; /** * 配置聯絡人到客戶的多對一關係 * 外來鍵欄位是設定在從表中的,且該欄位並未作為物件的屬性去配置,而實作為外來鍵去配置 * * 使用註解的形式配置多對一關係 * 1.配置表關係 * @ManyToOne : 配置多對一關係 * targetEntity:對方的實體類位元組碼 * 2.配置外來鍵(中間表) * * * 配置外來鍵的過程,配置到了多的一方,就會在多的一方維護外來鍵 * */ @ManyToOne(targetEntity = Customer.class, fetch = FetchType.LAZY) @JoinColumn(name = "lkm_cust_id", referencedColumnName = "cust_id") private Customer customer; }
先儲存customer物件後再呼叫linkMan的setter:
@Test public void oneManyTest() { Customer customer = new Customer(); LinkMan linkMan = new LinkMan(); customer.setCustName("TBD雲集中心"); customer.setCustLevel("VIP客戶"); customer.setCustSource("網路"); customer.setCustIndustry("商業辦公"); customer.setCustAddress("昌平區北七家鎮"); customer.setCustPhone("010-84389340"); linkMan.setLkmName("小明"); linkMan.setLkmGender("male"); linkMan.setLkmMobile("13811111111"); linkMan.setLkmPhone("010-34785348"); linkMan.setLkmEmail("[email protected]"); linkMan.setLkmPosition("老師"); linkMan.setLkmMemo("還行吧"); /** * 配置了客戶到聯絡人的關係 * 從客戶的角度上,傳送了兩條insert語句,傳送一條更新語句更新資料庫(更新從表中的外來鍵值) * 由於我們配置了客戶到聯絡人的關係,客戶可以對外來鍵進行維護 */ linkMan.setCustomer(customer); customerDao.save(customer); customer.getLinkManSet().add(linkMan); linkManDao.save(linkMan); }
參考:https://blog.csdn.net/qq_45002076/article/details/111415611