gpt4 book ai didi

java - Spring-Data JPA 持久化未引用的实体

转载 作者:行者123 更新时间:2023-11-30 11:22:06 24 4
gpt4 key购买 nike

我有以下实体

@Entity
public class A {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
// ... //

@ManyToOne(optional = false, fetch = FetchType.EAGER, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
@JoinColumn(name = "B_ID", nullable = false)
private B b;
}

@Entity
public class B {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Lob
private BitSet bitSet;
// ... //

@OneToMany(mappedBy = "b", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
Set<A> as;
}

在我的代码中,我有以下序列创建一个 A 并分配一个新的 B,稍后在代码中当服务类去保存 A 时,服务检查数据库中是否已经存在等效的 B,如果是,则将 A 的 B 替换为数据库中的 B。我知道这有点令人费解,但我们不希望创建 A 的代码了解数据库,而实际代码当然更复杂。

// Initialization code happens in one part
A a = new A();
a.setB( new B() ); // This new B get's saved even if it is replaced later!

// Later a service is used to save the new A
B repoB = bRepository.findOneByBitSet( a.getB().getBitSet() );
if (repoB != null) {
a.setB(repoB); // Replace the temporary B
} // Otherwise we will keep the original B.
aRepository.save(a);

好的,现在问题来了。 A 的原始 B 被保存到数据库中,即使这个新的 B 没有被任何对象引用。为什么 Spring-Data 会保存这个未引用的 B 对象。

如果我直接使用 Hibernate,我可以像这样在不需要的 B 上使用 evict(),但是 Spring-Data 不会公开这样的调用:

// Later a service is used to save the new A
B repoB = bRepository.findOneByBitSet( a.getB().getBitSet() );
if (repoB != null) {
B unwantedB = a.getB();
a.setB(repoB); // Replace the unwanted B
hibernate.evict(unwantedB);
} // Otherwise we will keep the original B.
aRepository.save(a);

一个更直接的场景示例是:

A a = new A();
B unwantedB = new B();
a.setB(unwantedB);
B b = newB();
a.setB(b);
repository.save(a);

对象“a”应该通过对对象“b”的引用来持久化,但我认为对象“unwantedB”不会持久化到数据库中。

最佳答案

Why would Spring-Data save this unreferenced B object.?

因为您在集合关联上使用 cascade = { CascadeType.MERGE, CascadeType.PERSIST })

If I were working directly with Hibernate I could have used an evict() on the unwanted B like so, but Spring-Data does not expose such a call

这是正确的,因此考虑将关系中 B 的字段设置为 null。这意味着删除从 A 到 B 的引用

a.setB( new B() );a.setB(null); persist if not entity 之前将添加一个 persist time

如果您不想在 B 中存储新实体,请删除级联选项。

关于java - Spring-Data JPA 持久化未引用的实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21917720/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com