java - 级联持久化具有未知 PK/FK 属性的 JPA 实体违反 NotNullConstraint

标签 java jpa eclipselink

我想通过一次persist调用来持久保存一个具有多个一对一或一对多关系的 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)的所有实体?

最佳答案

这里的情况是 ProtocolFile 的“派生身份” - ProtocolFile 的 ID 是 Protocol 的 ID并且它们之间是一对一的关系。

我发现您正在使用 updatable=false, insertable=false 但最好遵循建议使用 @MapsId 注释的规范:

@Entity
@Table(name = "PROTOCOL_FILE")
public class ProtocolFile {

    @Id // No @Column here
    private Long protocolId;

    @MapsId // --- HERE
    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
    @JoinColumn(name="PROTOCOL_ID") // Just that
    private Protocol protocol;
}

或者您可能想完全跳过 protocolId 字段,并将 @Id 注释放在关系上。

@Entity
@Table(name = "PROTOCOL_FILE")
public class ProtocolFile {

    @Id // --- HERE
    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
    @JoinColumn(name="PROTOCOL_ID") // Just that
    private Protocol protocol;
}

当然,您需要在创建过程中将protocol实例设置为file,并且以后不再更改它(例如,允许仅使用ProtocolFile构造函数)。

请参阅 JPA 2.0 spec 的“2.4.1 对应于派生身份的主键”部分了解更多详细信息和示例(示例 4 似乎就是您的情况)。

关于java - 级联持久化具有未知 PK/FK 属性的 JPA 实体违反 NotNullConstraint,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32627062/

相关文章:

java - java中如何写入文件?

java - CalendarContract:列“dtstart”无效(使用injectCalendar())

java - Spring : Use Hibernate types without hibernate. cgf.xml

hibernate - 删除未完成

database - 从外部源加载 Hibernate 属性 (HashMap)

java - Eclipselink实体类自动扫描发现非实体

java - JPA 如何为 @OneToMany 关系的列添加唯一约束,如用户名

tomcat - Spring 框架 Tomcat LoadTimeWeaving

java - 高负载场景下DatabaseAccessor未连接

java - 检索 JPQL、EclipseLink 和 MySQL 中的实体