如何在冬眠中具有两个多对多双向依赖性的实体



我在数据库中具有以下关系实体:

Table A <-- (One-to-Many) --> Table B
Table B <-- (One-to-Many) --> Table C
Table B <-- (Many-to-One) --> Table J
Table C <-- (Many-to-One) --> Table J

表B包含表A和J.表C包含表B和J。

的外键

注意:表B和C都包含一个外键参考(Table_j_id),引用表J。

您可以看到,表B和C都与表J都有多一关系。因此,我创建了以下双向实体:

@Entity
@Table(name="TableA")
public class TableA {
  @Id
  // Generates via a sequence object
  private Integer id;
  @OneToMany(mapped="tableATableB", cascade=CascadeType.All, orphanRemoval=true)
  private Set<TableB> tableBs = new LinkedHashSet<TableB>();
  public void addTableB(TableB b) {
    this.tableBs.add(b);
    b.setTableATableB(this);
  }
}
@Entity
@Table(name="TableB")
public class TableB {
  @Id
  // Generates via a sequence object
  private Integer id;
  @ManyToOne
  @JoinColumn(name="TABLE_J_ID")
  private TableJ tableJTableB;
  @ManyToOne
  @JoinColumn(name="TABLE_A_ID")
  private TableA tableATableB;
  @OneToMany(mapped="tableBTableC", cascade=CascadeType.All, orphanRemoval=true)
  private Set<TableC> tableCs = new LinkedHashSet<TableC>();
  public void addTableC(TableC c) {
    this.tableCs.add(c);
    b.setTableBTableC(this);
  }
}
@Entity
@Table(name="TableJ")
public class TableJ {
  @Id
  // Generates via a sequence object
  private Integer id;
  @OneToMany(mapped="tableJTableB", cascade=CascadeType.All)
  private Set<TableB> tableBs = new LinkedHashSet<TableB>();
  @OneToMany(mapped="tableJTableC", cascade=CascadeType.All)
  private Set<TableC> tableCs = new LinkedHashSet<TableC>();
  public void addTableB(TableB b) {
    this.tableBs.add(b);
    b.setTableJTableB(this);
  }
  public void addTableC(TableC c) {
    this.tableCs.add(c);
    b.setTableJTableC(this);
  }
}
@Entity
@Table(name="TableC")
public class TableC {
  @Id
  // Generates via a sequence object
  private Integer id;
  @ManyToOne
  @JoinColumn(name="TABLE_J_ID")
  private TableJ tableJTableC;
  @ManyToOne
  @JoinColumn(name="TABLE_B_ID")
  private TableB tableBTableC;
}    

构建对象图/树的方式:

TableA tableA = new TableA();
// Get a list of TableB's (bList) from an external call
// THIS BASICALLY ADDS TABLE B's to TABLE A and TABLE J
for (TableB b : bList) {
  TableJ j = new TableJ();
  j.addTableB(b);
  tableA.addTableB(b);
}
// Get a list of TableC's (cList) from an external call
// THIS BASICALLY ADDS TABLE C's to TABLE B and TABLE J
for (TableC c : cList) {
  for (TableB b : tableA.getTableBs()) {
    // Iterate through bList and find a match per some logic
    if (/* some logic to find a corresponding TableB */) {
      TableJ j = new TableJ();
      j.addTableC(c);
      b.addTableC(c);
    }
  }
}

执行代码时,我会收到以下错误:

**Unexpected error occurred in scheduled task.: org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientPropertyValueException: object TableB.tableJTableB -> class TableJ; nested exception in java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing: TableB.tableJTableB -> class TableJ
Caused by: java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing: TableB.tableJTableB -> class TableJ**

有人可以告诉我问题是什么?

问题是:

首先插入A。然后将A_ID用作B中的FK。b插入。B还需要J_ID FK,但j尚未存储=瞬态。

应更改JPA如何创建插入的顺序。需要J_ID来创建B,c。在将其添加到b之前,请坚持j。

for (TableB b : bList) {
  TableJ j = new TableJ();
  em.persist(j)
  j.addTableB(b);
  tableA.addTableB(b);
}

另外一个环

最新更新