1. 程式人生 > 實用技巧 >JPA插入時出現(save the transient before flushing) 解決辦法

JPA插入時出現(save the transient before flushing) 解決辦法

情景分析:

  出現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