#postgresql #spring-boot #hibernate #jpa #spring-data-jpa
Вопрос:
У меня есть Сущность 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
}
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
}
Создайте сущность
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()<>;
Комментарии:
1. Я уже пробовал это, когда добавлял КАСКАД. УПОРСТВОВАТЬ-это значит, что я отсоединяю сущность, переданную для сохранения.
2. Не могли бы вы, пожалуйста, опубликовать трассировку стека?
3. вызвано: org.спящий режим. PersistentObjectException: отделенная сущность, переданная в persist:EntityE в организации. зимовать. внутренний .SessionImpl.firePersist (SessionImpl.Java:744 ) в организации. зимовать. внутренний. SessionImpl.persist(SessionImpl.Java:712) в организации. hibernate.engine.spi.CascadingActions$7.каскад(CascadeActions.java:298)в организации. спящий режим.двигатель.внутренний. Cascade.cascadeToOne(Каскад.java:499) в организации. зимовать. двигатель. внутренний. Каскад.Каскадная ассоциация(Cascade.java:423) в организации. зимовать. двигатель. внутренний. Каскад.Свойство каскада (Каскад. Java:220)
4. Можете ли вы показать код, где вы его сохраняете? Где находятся границы транзакций?
5. Я заставил это работать, похоже, что метод сохранения, встроенный в jpa, не сработал. Я использовал entitymanger.merge, и это сработало нормально.