java - 保存时传递的分离实体持续存在
问题描述
我有一些代码,但它在 personRepository.save(person2) 处出现错误,无需解决此问题,只是为我解释为什么会抛出:分离的实体传递给坚持。
@Entity
public class Person {
@Id
@GeneratedValue
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@Column(name = "wallet_id", insertable = false, updatable = false)
private Long wallet_id;
@ManyToOne (fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "wallet_id",referencedColumnName = "id", insertable = true, updatable = true )
private Wallet wallet;
}
public void testSave(String name) {
Wallet walletNewNoHaveInDB = new Wallet(); // Generated id.
Person person = new Person(); // Generated id.
person.setName(name);
person.setWallet(walletNewNoHaveInDB);
personRepository.save(person); // This is OK and inserted into DB both(wallet , person).
Person person2 = new Person(); // Generated id.
person2.setName(name);
person2.setWallet(walletNewNoHaveInDB);
personRepository.save(person2); /// detached entity passed to persist
}
解决方案
我了解您没有使用 @Transactional 注释您的测试 - 在这种情况下,spring 正在为您创建事务以执行您所称的“保存”。更多信息在这里:https ://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions
在第一种情况下,您拥有“新”对象(没有 ID,并且不受 JPA 提供者管理),并且您确实指定了级联,因此 JPA 提供者知道如何将其保存在 1 个事务中。
在第二种情况下,您添加的钱包已经是托管对象,但没有交易。
您要么需要在@Transactional 范围内完成所有操作(注释您的测试),要么如果您从事务的“外部”传递对象(这是您的场景),再次......您需要有一个事务 - 所以您需要开始它并在来自它外部的对象上调用 merge() 。
推荐阅读
- typescript - Kotlin 等效于省略 TypeScript 实用程序类型
- python - 在 Python 中将 00 年转换为 2000 年
- html - 如何在 HTML 中使用带有订单列表的表格?
- java - 在 Java 中使用 XPATH 和 DOM 更新空 XML 元素
- javascript - 媒体管道图,在javascript中运行?
- ios - 如何通过 StoreKit 服务器通知检测用户是否仍在享受促销优惠
- xmpp - 在openfire中如何创建自定义机器人
- python - python socket [WinError 10038] 尝试对不是套接字的东西进行操作
- java - 如何在 Java 中到达堆栈底部(不丢失其他元素)
- python - Python 问题 Json 返回值是覆盖之前的值