繁体   English   中英

为什么 @OneToMany 在 JPA 与 springboot 中与 @JoinColumn 的单向关联会产生额外的查询

[英]why @OneToMany Unidirectional association with @JoinColumn in JPA with springboot generates extra queries

我正在做一个项目,我觉得在 @OneToMany 单向关联中与 @JoinColumn 在 JPA 中与 springboot 生成额外的查询。 例如,如果我们有 2 个实体

@Entity(name = "Post")
@Table(name = "post")
public class Post {
 
    @Id
    @GeneratedValue
    private Long id;
 
    private String title;
 
    @OneToMany(
        cascade = CascadeType.ALL,
        orphanRemoval = true
    )
    @JoinColumn(name = "post_id")
    private List<PostComment> comments = new ArrayList<>();
 
    //Constructors, getters and setters removed for brevity
}
 
@Entity(name = "PostComment")
@Table(name = "post_comment")
public class PostComment {
 
    @Id
    @GeneratedValue
    private Long id;
 
    private String review;
 
    //Constructors, getters and setters removed for brevity
}

当我们运行以下代码时

Post post = new Post("First post");
 
post.addComment(
    new PostComment("My first review")
);
post.addComment(
    new PostComment("My second review")
);
post.addComment(
    new PostComment("My third review")
);
 
entityManager.persist(post);

它生成以下查询

insert into post (title, id)
values ('First post', 1)
 
insert into post_comment (review, id)
values ('My first review', 2)
 
insert into post_comment (review, id)
values ('My second review', 3)
 
insert into post_comment (review, id)
values ('My third review', 4)
 
update post_comment set post_id = 1 where id = 2
 
update post_comment set post_id = 1 where id =  3
 
update post_comment set post_id = 1 where id =  4

现在我的问题是,为什么 JPA 在插入 post_comment 记录后更新 post_comment 记录? 为什么 JPA 在 post_comment 表中插入记录时不插入带有 post_id 的 post_comment 记录,这样它就不必再次更新记录?

您依赖CascadeType.ALL为您插入PostComments 这是为什么? 我认为这是一个 JPA 反模式。 JPA 指定关系的owner将保持关系。 请参阅如果关系是双向的,则必须使用 mappedBy 元素来指定作为关系所有者的实体的关系字段或属性。 您尚未指定关系的owner

您可以指出 JPA 规范中的哪些内容规定应以任何特定方式实施使用CascadeType

你展示的东西对我来说很有意义。 Post被保存, PostComments保存在CascadeType的 b/c 中,然后Post id 更新到PostComments中。 您没有自己将Post id 设置到PostComments中,因此您对实现方式没有任何发言权。 我已经看到CascaseType做了一些有趣的事情,但就我而言,它仍然是一种反模式。 如果您不了解它,请不要使用它!

除此之外,您还在评论中添加了 static = new ArrayList<>() 另一个反模式。 这些new ArrayLists中的大部分将在很短的时间内被扔到垃圾堆中。 即使 Java 为您管理 memory,您也应该知道如何使用它。

简短的回答, PostComments应该由您专门保存,但前提是您已经保存了Post并且准备好将其设置为PostComment 当然,你应该在PostComment中有PostManyToOne这样你就可以做到这一点。

我不知道你是否调查过相关EntitiesQuery行为,但我想你也会在那里发现更多惊喜。 因为我已经这样做了,所以我发表这些评论。

参考:

ORM 映射中的“拥有方”是什么?

37.1 实体

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM