【发布时间】:2020-04-11 22:14:59
【问题描述】:
我有两个实体,我们将它们称为 A 和 B。B 始终将 A 作为具有 ManyToOne 关系的父级。 但是,我需要 A 与表 B 中插入的最新记录建立 OneToOne 关系。 这是因为我需要保存多个版本的 B,但 99% 的时间只需要使用最新的版本。
这看起来像这样:
@Data
@Entity
public class A {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Setter(AccessLevel.NONE)
private Long id;
/* Properties
...
*/
@OneToOne(optional = false)
private B latest;
}
@Data
@Entity
public class B {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Setter(AccessLevel.NONE)
private Long id;
/* Properties
...
*/
@Column(nullable = false)
private Date lastModified;
@ManyToOne(optional = false)
private A parent;
}
现在,手头的问题是我似乎无法持久化这些实体,因为它们似乎总是短暂的:
- A 无法持久化,因为
latest引用了 B,但 B 没有持久化。 - B 无法持久化,因为
parent引用了 A,但 A 没有持久化。
尝试这样做会导致:
java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: 非空属性引用瞬态值 - 瞬态实例必须在当前操作之前保存:B.parent -> A
我尝试将负责持久化它们的代码包装在 @Transactional 方法中,但同样的情况发生了:
@Transactional
public void saveAB(A parent, B child) {
parent.setLatest(child);
child.setParent(parent);
Arepository.save(parent);
Brepository.save(child);
}
我还想过忽略从 A 到 B 的 OneToOne 关系,而是将 latest 作为临时的 @Formula 字段,它将查询 B 以获取最新记录。但是,@Formula 似乎仅限于原语,而不是完整的实体。
使用 JPA 执行此操作的正确方法是什么?我是不是走错了路?
【问题讨论】:
-
看看这个vladmihalcea.com/tutorials/hibernate -> 关系
-
@AhmetOZKESEK 谢谢。实际上,我在“高级映射技术”中找到了我的确切场景的示例:vladmihalcea.com/… 最初的 StackOverflow 问题没有得到很多赞成,所以我想我不是自然而然地偶然发现的。
标签: java spring hibernate jpa spring-data-jpa