Spring Data Jpa problem saving parent, child and childofchild in one transaction

Viewed 131

I have Entity A, B, C, D, E,F Entity A is parent of B, C, D Entity D is parent of E, F.

I have repository for entity A, when I am doing repo.save, It is only saving A,B,C,D and not E,F.
I am using predefined sequence from postgres.

create Entity A

@Entity
@Table(name="tname", schema="schemaname")
Public Class EntityA implements serializable
{
  @Id
  @SequenceGenerator()
  @column(name = "id")
  private int id;
   
  private string column1;
  private string column2;

  @OneToMany(cascade = CASCADE.ALL, mappedBy="entityA") 
  private set<EntityB> = new Hashset()<>;

  @OneToMany(cascade = CASCADE.ALL, mappedBy="entityB") 
  private set<EntityB> = new Hashset()<>;

  @OneToMany(cascade = CASCADE.ALL, mappedBy="entityC") 
  private set<EntityB> = new Hashset()<>;

  //getters and setters  

}

create Entity B

@Entity
@Table(name="tname", schema="schemaname")
Public Class EntityB implements serializable
{
  @Id
  @SequenceGenerator()
  @column(name = "id")
  private int id;
   
  private string column1;
  private string column2;

  @ManyToOne
  @joinColumn(name="EntityA.id", referencedColumn="EntityA.id")
  private EnityA entityA


  //getters and setters  ​
  //constructor

}

create Entity C

@Entity
@Table(name="tname", schema="schemaname")
Public Class EntityC implements serializable
{
  @Id
  @SequenceGenerator()
  @column(name = "id")
  private int id;
   
  private string column1;
  private string column2;

  @ManyToOne
  @joinColumn(name="EntityA.id", referencedColumn="EntityA.id")
  private EnityA entityA


  //getters and setters  ​
  //constructor

}

create Entity D

@Entity
@Table(name="tname", schema="schemaname")
Public Class EntityD implements serializable
{
  @Id
  @SequenceGenerator()
  @column(name = "id")
  private int id;


  @ManyToOne
  @joinColumn(name="EntityA.id", referencedColumn="EntityA.id")
  private EnityA entityA
   
  private string column1;
  private string column2;

  @OneToMany(cascade = CASCADE.MERGE, mappedBy="entityD") 
  private set<EntityE> = new Hashset()<>;

  @OneToMany(cascade = CASCADE.MERGE, mappedBy="entityD") 
  private set<EntityF> = new Hashset()<>;
  

  //getters and setters  ​
  //constructor

}

create Entity E

@Entity
@Table(name="tname", schema="schemaname")
Public Class EntityE implements serializable
{
  @Id
  @SequenceGenerator()
  @column(name = "id")
  private int id;
   
  private string column1;
  private string column2;

  @ManyToOne
  @joinColumn(name="EntityD.id", referencedColumn="EntityD.id")
  private EnityD entityD


  //getters and setters  ​
  //constructor

}

create Entity F

@Entity
@Table(name="tname", schema="schemaname")
Public Class EntityF implements serializable
{
  @Id
  @SequenceGenerator()
  @column(name = "id")
  private int id;
   
  private string column1;
  private string column2;

  @ManyToOne
  @joinColumn(name="EntityD.id", referencedColumn="EntityD.id")
  private EnityD entityD


  //getters and setters  ​
  //constructor

}

Build the EntityA

Public class EntityABuilder
{
 EntityA a = new EntityA();
 a.setColumn1("test");

 //build B
 Set<EntityB> bSet = a.getEntityB();
 EnityB b = new EntityB();
 b.setColumn1("btest");
 bSet.add(b);

//for each B setA
for(EntityB bs:bSet)
{
 bs.setEntityA(a);
}

//build C
 Set<EntityC> cSet = a.getEntityC();
 EnityC c = new EntityC();
 c.setColumn1("ctest");
 cSet.add(c);

//for each c set A
for(EntityC cs:cSet)
{
 cs.setEntityA(a);
}

//build D
Set<EntityD> dSet = a.getEntityD();
 EnityD d = new EntityD();
 d.setColumn1("btest");

 //build EntityE
 Set<EntityE> ESet = D.getEntityE();
 EntityE e = new EntityE();
 e.setCloumn1("eTest")
 eset.add(e);

//for each E set D
  for(EntityE es:eSet)
  {
   es.setEntityD(d);
  }

  //build EntityF
  Set<EntityF> fSet = D.getEntityE();
 EntityF f = new EntityF();
 f.setCloumn1("eTest")
 fSet.add(f);

  //foe each F set D
  for(EntityF fs:fSet)
  {
   fs.setEntityD(d);
  }

//add D
 dSet.add(d);

//for each D set A
for(EntityD ds:dSet)
{
 ds.setEntityA(a);
}
}

calling EntityARepository.save(EntityA) it saves A,B,C,D and not E,F.

1 Answers

You have only set CASCADE.MERGE but as you are creating new entities you also need to set CASCADE.PERSIST

@OneToMany(cascade = {CASCADE.PERSIST, CASCADE.MERGE}, mappedBy="entityD") 
private set<EntityE> = new Hashset()<>;

@OneToMany(cascade = {CASCADE.PERSIST, CASCADE.MERGE}, mappedBy="entityD") 
private set<EntityF> = new Hashset()<>;
Related