Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/401.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA/Hibernate使用共享id和cascade=all尝试在父级之前保存子级,导致外键冲突_Java_Hibernate_Jpa_Parent Child_Persist - Fatal编程技术网

Java JPA/Hibernate使用共享id和cascade=all尝试在父级之前保存子级,导致外键冲突

Java JPA/Hibernate使用共享id和cascade=all尝试在父级之前保存子级,导致外键冲突,java,hibernate,jpa,parent-child,persist,Java,Hibernate,Jpa,Parent Child,Persist,我将JPA与hibernate一起使用。我有一个1对1的父子关系(子关系是可选的),id在两者之间共享,子表上有一个外键关系。我的实体如下所示: 家长: public class LogItemEntity { ... @OneToOne(cascade={CascadeType.ALL}, mappedBy = "logItem", orphanRemoval=true, optional=true) @PrimaryKeyJoinColumn(referencedColum

我将JPA与hibernate一起使用。我有一个1对1的父子关系(子关系是可选的),id在两者之间共享,子表上有一个外键关系。我的实体如下所示:

家长:

public class LogItemEntity {
...

    @OneToOne(cascade={CascadeType.ALL}, mappedBy = "logItem", orphanRemoval=true, optional=true)
    @PrimaryKeyJoinColumn(referencedColumnName="ral_id")
    private LogAdditionalRequirement additionalRequirement;
...
}
儿童:

public class LogAdditionalRequirement {
...
    @Id
    @GeneratedValue(generator = "foreign")
    @GenericGenerator(name = "foreign", strategy = "foreign", parameters = { @Parameter(name = "property", value = "logItem") })
    @Column(name = "ral_id")
    private Long id;

    @OneToOne(optional=false)
    @PrimaryKeyJoinColumn(referencedColumnName="id")
    private LogItemEntity logItem;
...
}
插入新对象时,父对象的id由序列生成,级联操作将其复制到子对象上。但子对象的sql插入被放置在会话的操作队列中,先于父对象的sql插入,因此它失败,外键上的约束冲突:

ERROR o.h.util.JDBCExceptionReporter - ERROR: insert or update on table "rar_log_additional_requirement" violates foreign key constraint "fk_rar_ral_id"
Detail: Key (ral_id)=(70150) is not present in table "ral_log".
那么,如何才能首先插入父对象呢


这一定是一个非常常见的用法,所以我假设我做错了什么,但我不知道它是什么。我最初在child端有mappedBy属性。我认为这是错误的,但把它换一次也没什么区别。

一个解决方案可能是删除cascade“cascade={CascadeType.ALL}”


关于这个主题的更多信息

谢谢,但是如果我这样做,我不需要显式保存子对象吗?否则,我将在flush()上获得TransientObject异常。父级实际上包含几个像这样的子级,其中大多数是可选的,因此这意味着要添加一堆我想要避免的额外代码。顺便说一句,使用@ElementCollection的集合的行为似乎完全不同,它们在刷新时被持久化,根本不需要任何特定的处理。也许我可以(ab)使用单例集合?是的,请参阅:“ElementCollection上没有级联选项,目标对象总是与其父对象一起持久化、合并和删除。”您遇到的问题很可能与构造和保存新实例的方式有关。发布相关代码。我正在使用Spring JpaRepository,因此我在父级和子级之间设置了引用,并调用JpaRepository.save(),因此:logItemEntity.setAdditionalRequirement(additionalRequirement);附加要求.setLogItem(logItemEntity);jpaRepository.save(logItemEntity);我不知道您想要实现什么,所以我有这个答案,但是:可能对您有帮助。我想要一个父实体,带有可选的子实体,并且我想要持久化父实体和子实体(如果存在)用一个方法调用。你能展示你创建新实体的代码和保存它的代码吗?我还注意到你在两侧都定义了@PrimaryKeyJoinColumn,这似乎不正确。请参见这里的一个简单示例。