情景分析:
出现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