【发布时间】:2020-07-29 12:40:47
【问题描述】:
下面是我们两个实体的映射。它们包含多对一关系。
实体 A:
@ManyToOne(targetEntity = First.class)
@JoinColumns({
@JoinColumn(name = "seq", referencedColumnName = "seq", insertable = false, updatable = false),
@JoinColumn(name = "addrSeq", referencedColumnName = "addrSeq", insertable = false, updatable = false) })
@IndexedEmbedded
private Second second;
public Second getSecond() {
return second;
}
public void setSecond(Second second) {
this.second= second;
}
实体 B:
@OneToMany(mappedBy="second", targetEntity = First.class)
@ContainedIn
private Set<First> first;
JPA 详细信息:
使用org.springframework.data.jpa.repository.JpaRepository的save()方法来持久化数据。
作为: 回购类:
public interface FirstRepository extends JpaRepository<First, FirstID>{}
然后在控制器中我们首先设置.. First 实体的所有数据设置器,然后:
repository.save(first);
现在的问题是,当尝试持久化第一个实体时,hibernate 会尝试持久化第二个实体,当它发现对象为空白时,它会为第二个实体抛出以下错误:
对象引用了一个未保存的瞬态实例 - 保存瞬态 刷新前的实例
是否可以在第一个实体和第二个实体之间仅出于休眠搜索(弹性索引)目的而建立只读关系。 因为我只需要弹性索引中第一个实体中的第二个实体的索引数据,并且在第一个实体上执行这些操作时永远不会添加/更新/删除第二个实体。此外,我们使用 JPA 来持久化第一个实体。
此外,我们不会在 Elastic 上索引第二个实体。但它确实包含@Field 带注释的字段,并且这些字段被嵌入到索引中的父字段中(这工作正常)。
另外,如果我在运行时向第一个实体内的第二个实体提供数据,然后再持久化第一个实体,它就可以工作。但它不会在持久化时自动拾取关系。
我已经尝试过的几件事:
- 使用 Cascade 和 Fetch 类型属性。
- 在
@IndexedEmbedded private Second second;上使用@Transient,则没有遇到问题,但第二个实体的索引上没有数据。
【问题讨论】:
-
"对象引用了一个未保存的瞬态实例——在刷新之前保存瞬态实例" => 这通常表明当你持久化它时你的实体有问题。这可能与您的映射无关,但与您调用的 getter/setter 无关。您能否澄清一下:“但它不会在持久性时自动拾取关系”?
-
@yrodiere,我已经用我的 getter/setter 更新了这个问题。请看看这些是否不正确或者需要更多的东西来做,我正在尝试做什么。进一步通过“但在持久性时它没有自动获取关系”我的意思是,当我在调试中检查第一个实体时,第二个实体是完全空的。我认为这很好,并且可能是休眠在持久化时创建了这种关系
-
getter/setter 的实现并不重要,我完全期望它们会以这种方式实现。重要的是调用这些 setter 和调用
entityManager.persist()的代码。 -
@yrodiere,我已经用我们正在使用的 JPA 存储库更新了答案。我们直接使用“org.springframework.data.jpa.repository”的save()方法进行持久化。有没有我应该研究或与您分享的特定领域,以便您对此有更清晰的了解。请为我分享路线。此外,在保留父第一个实体之前,我没有为第二个实体调用任何设置器(这就是您所说的“重要的是调用这些设置器的代码”)
标签: hibernate jpa hibernate-search