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("123456@qq.com");
        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

posted @ 2021-01-20 12:01  yhliln  阅读(405)  评论(0编辑  收藏  举报