首页 > 解决方案 > 为什么我需要 @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异常而在另一个样本中没有?

谁能解释为什么会这样?

标签: springspring-boothibernatejpaspring-data-jpa

解决方案


你不应该分别保存这两个实体——你应该在 post 对象中设置 PostDetail 并只保存 Post 对象。Hibernate 将负责保存聚合的 PostDetail。

这就是为什么您PersistentObjectException可以通过将其保存在同一个事务中来解决问题的原因。


推荐阅读