一次性节省两个 parents 和一个 child Spring JPA

Saving in one shot two parents and one child Spring JPA

我从来没有遇到过一次要保存多个 parent 和一个 child 的情况。在我的例子中,我有两个 parent 个实体和一个 child。两个 parent 实体在 child 实体上有一个外键。

我有一个这样的例子 ->

@Entity
@Table("parentA")
public class ParentA
{
@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long ID; 

@OneToMany(cascade = CascadeType.ALL, mappedBy="parentA")
private List<Child> child;

// Getters and Setters and some methods
}



@Entity
@Table("ParentB")
public class ParentB
{

@Column("CODE")
private Long code;

@OneToMany(cascade = CascadeType.ALL, mappedBy="parentB")
private List<Child> child;

// Getters and Setters and some methods}

@Entity
@Table("Child")
public class Child
{  
@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column("ID")
private Long ID;

@Column("parentA_ID")
private Long parentAId;

@Column("code")
private String code;//from parentB

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ID", referencedColumnName = "parentA_ID")
private ParentA parentA;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "code", referencedColumnName = "code")
private ParentB parentB;
// Getters and Setters and some methods}

您只需将属性 cascade = CascadeType.PERSIST 添加到 Child 字段:

@Entity
public class Child {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
    @JoinColumn
    private ParentA parentA;

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
    @JoinColumn
    private ParentB parentB;

    // ...
}

public interface ChildRepository extends JpaRepository<Child, Integer> {
}

那么当你保存子实体时父实体也会被保存:

ChildRepository childRepo;

// ...

    var child = new Child();
    var parentA = new ParentA();
    var parentB = new ParentB();

    parentA.setChild(List.of(child));
    parentB.setChild(List.of(child));
    child.setParentA(parentA);
    child.setParentB(parentB);

    childRepo.save(child);

您可以看到一个 save 插入了所有三行:

DEBUG n.t.d.l.l.SLF4JQueryLoggingListener - 
Name:dataSource, Connection:4, Time:52, Success:True
Type:Prepared, Batch:False, QuerySize:1, BatchSize:0
Query:["insert into parenta values ( )"]
Params:[()]
DEBUG n.t.d.l.l.SLF4JQueryLoggingListener - 
Name:dataSource, Connection:4, Time:0, Success:True
Type:Prepared, Batch:False, QuerySize:1, BatchSize:0
Query:["insert into parentb values ( )"]
Params:[()]
DEBUG n.t.d.l.l.SLF4JQueryLoggingListener - 
Name:dataSource, Connection:4, Time:0, Success:True
Type:Prepared, Batch:False, QuerySize:1, BatchSize:0
Query:["insert into child (parenta_id, parentb_id) values (?, ?)"]
Params:[(3,3)]