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



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

@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将持久化关系。如果关系是双向的,则必须使用mapappedby元素来指定关系字段或关系所有者实体的属性。您没有指定关系的owner

在JPA规范中,您可以指出哪些规定使用CascadeType应该以任何特定的方式实现?

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

除此之外,您还在注释上添加了静态= new ArrayList<>()。另一个反模式。这些new ArrayLists中的大多数将在很短的时间内被扔进垃圾堆。即使Java为您管理内存,您也应该对如何使用它有所了解。

简短的回答,PostComments应该由你具体保存,但只有当你已经保存了Post,它准备被设置为PostComment。当然,你应该在PostComment中有PostManyToOne,这样你就可以这样做了。

我不知道你是否调查了相关EntitiesQuery行为,但我认为你也会发现更多的惊喜。既然我已经这样做了,我做了这些评论。

引用:

什么是"拥有方"?在ORM映射中?

37.1实体

最新更新