Spring Data Jpa问题在一个事务中保存父,子和childofchild
Posted
技术标签:
【中文标题】Spring Data Jpa问题在一个事务中保存父,子和childofchild【英文标题】:Spring Data Jpa problem saving parent, child and childofchild in one transaction 【发布时间】:2021-12-05 15:58:25 【问题描述】:我有实体 A、B、C、D、E、F 实体 A 是 B、C、D 的父实体 实体 D 是 E、F 的父实体。
我有实体 A 的存储库,当我执行 repo.save 时,它只保存 A、B、C、D 而不是 E、F。 我正在使用来自 postgres 的预定义序列。
创建实体 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
创建实体 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
创建实体 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
创建实体 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
创建实体 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
创建实体 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
构建实体A
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);
调用 EntityARepository.save(EntityA) 它保存 A、B、C、D 而不是 E、F。
【问题讨论】:
【参考方案1】:您只设置了CASCADE.MERGE
,但在创建新实体时,您还需要设置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()<>;
【讨论】:
我已经尝试过了,当我添加 CASCADE.PERSIST 时,它会抛出我传递给持久化的分离实体。 你能发布堆栈跟踪吗? 引起:org.hibernate.PersistentObjectException:分离的实体传递给persist:org的EntityE。冬眠。 org 的内部 .SessionImpl.firePersist (SessionImpl.Java:744)。冬眠。 internal.SessionImpl.persist(SessionImpl.Java:712) 在 org. hibernate.engine.spi.CascadingActions$7.cascade(CascadeActions.java:298) at org. hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:499) at org.冬眠。引擎。 internal.Cascade.cascadeAssociation(Cascade.java:423) 在 org.冬眠。引擎。 internal.Cascade.cascadeProperty (Cascade.Java:220) 你能显示你保存的代码吗?交易边界在哪里? 我得到了这个工作,看起来 jpa 内置的保存方法不起作用。我使用了 entitymanger.merge 并且效果很好。以上是关于Spring Data Jpa问题在一个事务中保存父,子和childofchild的主要内容,如果未能解决你的问题,请参考以下文章
spring data jpa使用spring data jpa时,关于service层一个方法中进行删除和插入两种操作在同一个事务内处理