具有未知PK/FK属性的java级联持久化JPA实体违反了NotNullConstraint
我想用一个对persist
的调用来持久化一个具有多个1:1或1:多关系的JPA实体
问题:实体的主键自动生成,并用作子实体中的外键。提交事务时,会出现一个异常,指出子实体的外键列上违反了NotNullConstraint
Internal Exception: java.sql.SQLException: ORA-01400: Insertion of NULL in ("SCHEMA"."PROTOCOL_FILE"."PROTOCOL_ID") not possible
母公司:
@Entity
@Table(name = "...")
public class Protocol {
@Id
@GeneratedValue(generator="SQ_PROTOCOL", strategy=GenerationType.SEQUENCE)
@SequenceGenerator(name="SQ_PROTOCOL", sequenceName="SQ_PROTOCOL", allocationSize=50)
@Column(name = "PROTOCOL_ID")
private Long protocolId;
@OneToOne(mappedBy="protocol", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private ProtocolFile file;
//Other attributes and getter/setter omitted
}
子实体:
@Entity
@Table(name = "PROTOCOL_FILE")
public class ProtocolFile {
@Id
@Column(name = "PROTOCOL_ID")
private Long protocolId;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
@JoinColumns(@JoinColumn(name="PROTOCOL_ID", referencedColumnName="PROTOCOL_ID", updatable=false, insertable=false))
private Protocol protocol;
//Other attributes and getter/setter omitted
}
您知道一个方便的解决方案吗,这样我就可以在一次调用中持久化属于Protocol
的所有实体
# 1 楼答案
这里的情况是
ProtocolFile
的“派生身份”——这个ProtocolFile
的ID是Protocol
的ID,它们之间存在一对一的关系我看到您正在使用
updatable=false, insertable=false
,但最好遵循建议使用@MapsId
注释的规范:或者,您可能希望完全跳过
protocolId
字段,并在关系上添加@Id
注释当然,您需要在创建期间将
protocol
实例设置为file
,以后不再更改它(例如,只允许使用ProtocolFile
构造函数设置它)有关更多详细信息和示例,请参见JPA 2.0 spec的“2.4.1与派生标识相对应的主键”部分(示例4似乎就是您的情况)