未找到具有2个外键的模型中的ParentKey错误

时间:2019-06-28 06:22:25

标签: java spring hibernate jpa spring-data-jpa

我有以下型号;

// 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 BD的列表。(无需添加C对象)。我通过对象C添加了对象A,因为CA的真正关系是问题。问题是我在{{ 1}}春天引发以下异常;

Object C

我发现spring先保存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的条目,spring抛出了错误。保存B对象时。有什么办法可以解决这个问题?

PS:我无权更改数据库结构

PSS:这是C的表结构;

Object B

因此,我将CPK compositekey(A+B+C) FK A (number) FK B (number) FK D (number) lasteditedTime (time) 的ID手动添加到A, B并设置每个对象。

1 个答案:

答案 0 :(得分:0)

您的映射不正确。

您需要将@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;
}

对于与B的关系,您需要在C中进行类似的更改。在没有这些更改的情况下,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;
}