我有以下型号;
// 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
的真正关系是问题。问题是我在{{ 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
因此,我将C
和PK compositekey(A+B+C)
FK A (number)
FK B (number)
FK D (number)
lasteditedTime (time)
的ID手动添加到A, B
并设置每个对象。
答案 0 :(得分:0)
您的映射不正确。
您需要将@Id
直接放在关系上:
那么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;
}