Home > OS >  Saving in one shot two parents and one child Spring JPA
Saving in one shot two parents and one child Spring JPA

Time:01-09

I have never had a case where I want to save multiple parents and one child in one shot. In my case, I have two parent entities and one child. The two parent entities have a foreign key on the child entity.

I have an example like this ->

@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}

CodePudding user response:

You just add attribute cascade = CascadeType.PERSIST to Child fields:

@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> {
}

Then the parent entities will be saved when you save the child entity:

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);

You can see that a single save inserted all three rows:

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)]
  •  Tags:  
  • Related