SpringDataJPA存储库具有Hibernate-persist(SQLInsert)父实体,但仅更新嵌套的子实体
我正在用Spring数据、JPA、Hibernate组合开发一个Spring启动应用程序。下面是我正在努力解决的场景,预期的行为是在父实体作为新实体插入时只更新一些子实体 实体类 到目前为止,我可以从网上收集到关于这个主题的信息: JPA存储库没有明确可用的merge()或update()操作,save()应该涵盖这些操作。如果实体实例已经存在,则此save()操作通过调用merge()工作;如果实体实例是新实例,则通过调用persist()工作。进一步挖掘,实体的ID列被用来确定其在回购协议中的存在。若该ID为null,则实体被确定为新实体,若ID不为null,则实体被确定为现有实体 因此,在我上面的失败案例中,由于现有的SpringDataJPA存储库具有Hibernate-persist(SQLInsert)父实体,但仅更新嵌套的子实体,spring,hibernate,jpa,orm,spring-data,Spring,Hibernate,Jpa,Orm,Spring Data,我正在用Spring数据、JPA、Hibernate组合开发一个Spring启动应用程序。下面是我正在努力解决的场景,预期的行为是在父实体作为新实体插入时只更新一些子实体 实体类 到目前为止,我可以从网上收集到关于这个主题的信息: JPA存储库没有明确可用的merge()或update()操作,save()应该涵盖这些操作。如果实体实例已经存在,则此save()操作通过调用merge()工作;如果实体实例是新实例,则通过调用persist()工作。进一步挖掘,实体的ID列被用来确定其在回购协议中
B
实体实例正在从repo中提取,它已经有一个非空ID
所以我现在还不清楚我到底错过了什么。
我试图在网上找到任何匹配的解决方案,但还没有找到
有人能帮我找出我的方法有什么问题吗?找到了问题和解决方案。由于A和B被创建为新的,随后C、D、E都被创建为新的,这导致了违规。因此,为了解决这个问题,我必须从数据库中提取C、D和E的每个现有实体,并在新创建的B实体中分别/分层地设置它们,然后再尝试持久化
基本上,如果实体嵌套在将要持久化的父实体中,则不要为该实体创建新实例。。目标是在已经存在类似记录时进行更新。找到了问题和解决方案。由于A和B被创建为新的,随后C、D、E都被创建为新的,这导致了违规。因此,为了解决这个问题,我必须从数据库中提取C、D和E的每个现有实体,并在新创建的B实体中分别/分层地设置它们,然后再尝试持久化
基本上,如果实体嵌套在将要持久化的父实体中,则不要为该实体创建新实例。。我们的目标是在已经存在类似记录时进行更新。显示
a
-E
的代码,仅包括关联(不需要其他属性)。感谢您的查找!我已经在帖子中添加了模型[A到E],这个问题还不清楚。你说当B
已经存在时,C
、D
和E
保持不变,但是你在D
和E
上得到了一个唯一的约束冲突,这只有在D
和E
上尝试插入时才会发生,根据你的说法,这两种情况是没有尝试的。听起来不对。这是特定于您的应用程序的调试问题。请向我们显示a
-E
的代码,仅包括关联(不需要其他属性)。感谢您的查看!我已经在帖子中添加了模型[A到E],这个问题还不清楚。你说当B
已经存在时,C
、D
和E
保持不变,但是你在D
和E
上得到了一个唯一的约束冲突,这只有在D
和E
上尝试插入时才会发生,根据你的说法,这两种情况是没有尝试的。听起来不对。这是特定于应用程序的调试问题。
@Entity
public class A {
@Id
private long id;
@ManyToOne
@JoinColumn (name = "B_ID")
@Cascade ( { CascadeType.ALL } )
private B b;
}
@Entity
@DynamicUpdate
public class B {
@Id
private long id;
@OneToMany (mappedBy = "b")
@Cascade ( { CascadeType.ALL } )
private Set<A> as;
@ManyToOne
@JoinColumn (name = "C_ID")
@Cascade ( { CascadeType.ALL } )
private C c;
}
@Entity
@DynamicUpdate
public class C {
@Id
private long id;
@OneToMany (mappedBy = "c")
@Cascade ( { CascadeType.ALL } )
private Set<B> bs;
@ManyToOne
@JoinColumn (name = "D_ID")
@Cascade ( { CascadeType.ALL } )
private D d;
@ManyToOne
@JoinColumn (name = "E_ID")
@Cascade ( { CascadeType.ALL } )
private E e;
}
@Entity
@DynamicUpdate
public class D {
@Id
private long id;
@OneToMany (mappedBy = "d")
@Cascade ( { CascadeType.ALL } )
private Set<C> cs;
}
@Entity
@DynamicUpdate
public class E {
@Id
private long id;
@OneToMany (mappedBy = "e")
@Cascade ( { CascadeType.ALL } )
private Set<C> cs;
}
• ID as auto-generated column (used as PK implicitly),
• Mapping between entities using the ID column,
• CascadeType ALL wherever mappings like OneToMany, ManyToOne are applied,
• Dynamic update annotation.