Ошибка ParentKey не найдена в модели с двумя внешними ключами - PullRequest
0 голосов
/ 28 июня 2019

У меня есть следующие модели:

// A

class A {
   @Id
   private int id;
   @Id
   @Column(name = "D",
        nullable = false,
        precision = 20,
        scale = 0
   )
   private Long dId;

   @ManyToOne
   @JsonManagedReference
   @JoinColumn(
        name = "D",
        nullable = false,
        insertable = false,
        updatable = false
)
   private D d;

   @OneToMany(mappedby = "a",
        fetch = FetchType.LAZY,
        cascade = CascadeType.ALL,
        orphanRemoval = true )
   Set<C> Cs;
}

// B

class B {
   @Id
   int id;
  @Column(name = "D",
        nullable = false,
        precision = 20,
        scale = 0
  )
   private Long dId;

   @ManyToOne
   @JsonManagedReference
   @JoinColumn(
        name = "D",
        nullable = false,
        insertable = false,
        updatable = false
)
   private D d;

   @OneToMany(mappedby = "b",
        fetch = FetchType.LAZY,
        cascade = CascadeType.ALL,
        orphanRemoval = true )
   Set<C> Cs;
}

// C

class C {
   @Id
   int id;
   String name;
   @ManyToOne
   @JsonManagedReference
   @JoinColumns(

        {
                @JoinColumn(name = "A", insertable = false, updatable = false),
                @JoinColumn(name = "D", insertable = false, updatable = false)

        }
)
private A a;

@ManyToOne
@JsonManagedReference
@JoinColumns(
        {

                @JoinColumn(name = "B", insertable = false, updatable = false),
               @JoinColumn(name = "D", insertable = false, updatable = false)
        }
)
private B B;


@Id
@Column(name = "D",
        nullable = false,
        precision = 20,
        scale = 0)
private Long dId;

@Id
@Column(name = "B",
        nullable = false,
        precision = 3,
        scale = 0)
private Integer bId;

@Id
@Column(name = "A",
       nullable = false,
        precision = 5,
        scale = 0)
private Integer aId;
}

// D

 class D{
   @Id
   int id;

   @OneToMany(mappedby = "d",
        fetch = FetchType.LAZY,
        cascade = CascadeType.ALL,
        orphanRemoval = true )
   Set<A> As;
  @OneToMany(mappedby = "d",
        fetch = FetchType.LAZY,
        cascade = CascadeType.ALL,
        orphanRemoval = true )
   Set<B> Bs;
}

Так что здесь все сохраняется через class D.(Это означает, что я установил модель и сохранил в хранилище D.) Я могу без проблем сохранить список объектов с A and B по D (без добавления объектов C).Я добавляю объекты C через объект A, поскольку реальные отношения C связаны с A. Проблема заключается в том, что я добавляю пружинные броски Object C на Object A после исключения;

Caused by: java.sql.SQLIntegrityConstraintViolationException: ORA-02291: integrity constraint (XYZ.RELATIONSHIP0123) violated - parent key not found

        at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:450)
        at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:399)
        at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1017)
        at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:655)
        at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:249)
        at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:566)
        at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:215)
        at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:58)
        at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:943)
        at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1075)
        at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3820)
        at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3897)
        at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1361)
        at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:204)
        ... 98 more

Я обнаружил, что пружина сначала сохраняет A объекты, а затем перемещается в C объекты перед сохранением B объектов, так что бросок пружины выше ошибки, так как нет записи Object B, когда C объектыэкономии.Есть ли способ решить эту проблему?

PS: У меня нет разрешения изменять структуру БД

PSS: Это структура таблицы C;

PK compositekey(A+B+C)
FK A (number)
FK B (number)
FK D (number)
   lasteditedTime (time)

Поэтому я вручную добавляю идентификаторы A, B и D s к C object и устанавливаю каждый объект.

1 Ответ

0 голосов
/ 28 июня 2019

Ваши отображения неверны.

Вам необходимо поместить @Id непосредственно в отношение:

https://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Primary_Keys_through_OneToOne_and_ManyToOne_Relationships

Итак, случай A:

class A {
   @Id
   private int id;

   //@Id
   //@Column(name = "D")
   //private Long dId;

   @Id //added
   @ManyToOne
   @JsonManagedReference
   @JoinColumn(
        name = "D",
        nullable = false,
        insertable = false,
        updatable = false
   )
   private D d;

   @OneToMany(mappedby = "a",
        fetch = FetchType.LAZY,
        cascade = CascadeType.ALL,
        orphanRemoval = true )
   Set<C> Cs;
}

Необходимо внести аналогичные изменения в C для отношений с B. Без этих изменений Hibernate не имеет представления о том, что A зависит от D, а C зависит от B для идентичностей.

Как правило, вы также можете создать класс Id или EmbeddedID, однако Hibernate допускает несколько полей ID без этого.

Если вы хотите сохранить поле dId, вы можете использовать @MapsId.Я думаю, что это будет выглядеть ниже.

class A {
   @Id
   private int id;

   @Id
   @Column(name = "D")
   private Long dId;

   @MapsId("dId") //added
   @ManyToOne
   @JsonManagedReference
   @JoinColumn(
        name = "D",
        nullable = false,
        insertable = false,
        updatable = false
   )
   private D d;

   @OneToMany(mappedby = "a",
        fetch = FetchType.LAZY,
        cascade = CascadeType.ALL,
        orphanRemoval = true )
   Set<C> Cs;
}
...