spring - 为什么我需要 @Transactional 来保存 OneToOne 映射的实体
问题描述
我有一个简单直接的演示应用程序,其中包含 spring-boot、spring-data-jpa 和 h2-DB。
我已经建立了两个由OneToOne
关系映射的实体。
Post.java
@Entity
public class Post {
@Id
@GeneratedValue
private Long id;
private String title;
@OneToOne(mappedBy = "post", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private PostDetail postDetail;
}
PostDetail.java
@Entity
public class PostDetail {
@Id
@GeneratedValue
private Long id;
private String message;
@OneToOne(fetch = FetchType.LAZY)
@MapsId
@JoinColumn(name = "id")
private Post post;
}
我尝试创建并保存一个新的Post
. 然后我尝试创建一个新的PostDetail
,将以前生成的设置Post
为它并保存它。在一个控制器示例中,我没有@Transactional
注释,而在第二个示例中,我使用@Transactional
@RestController
public class TestController {
@Autowired
PostRepository postRepository;
@Autowired
PostDetailRepository postDetailRepository;
@GetMapping("/test1")
public String test1() {
Post post = new Post();
post.setId(2L);
post.setTitle("Post 1");
postRepository.save(post);
PostDetail detail = new PostDetail();
detail.setMessage("Detail 1");
detail.setPost(post);
postDetailRepository.save(detail);
return "";
}
@Transactional
@GetMapping("/test2")
public String test2() {
Post post = new Post();
post.setId(2L);
post.setTitle("Post 1");
postRepository.save(post);
PostDetail detail = new PostDetail();
detail.setMessage("Detail 1");
detail.setPost(post);
postDetailRepository.save(detail);
return "";
}
}
为什么我在第一个样本中出现org.hibernate.PersistentObjectException: detached entity passed to persist: com.example.demo.jpa.model.Post
异常而在另一个样本中没有?
谁能解释为什么会这样?
解决方案
你不应该分别保存这两个实体——你应该在 post 对象中设置 PostDetail 并只保存 Post 对象。Hibernate 将负责保存聚合的 PostDetail。
这就是为什么您PersistentObjectException
可以通过将其保存在同一个事务中来解决问题的原因。
推荐阅读
- javascript - 如何限制浏览器的最小可调整宽度?
- virtualenv - 如何更改已经存在的 virtualenv 的 python 版本?
- twitter-bootstrap - 引导日期时间选择器时间未显示在编辑页面上,为什么?
- hadoop - 我在该文本文件中有一个文本文件,其中包含一些字符数据。在该数据中没有分隔符,也没有空格
- javascript - ReactJS 待办事项列表应用删除功能
- python - 如何在python中的两个集合的交集中添加重复项
- javascript - 如何实现动态 html 表单以使用连接线水平和垂直添加输入元素
- bash - 使用 sed 脚本生成 awk 脚本
- python - tkinter:动态更改标签文本而不重复如果测试
- javascript - 节点树的递归追加