我正在做一个项目,我觉得在@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,然后Post
id更新为PostComments
。您没有自己将Post
id设置为PostComments
,因此您对实现如何执行它没有任何发言权。我已经看到CascaseType
做了一些有趣的事情,但就我而言,它仍然是一个反模式。如果你不理解它,就不要使用它!
除此之外,您还在注释上添加了静态= new ArrayList<>()
。另一个反模式。这些new ArrayLists
中的大多数将在很短的时间内被扔进垃圾堆。即使Java为您管理内存,您也应该对如何使用它有所了解。
简短的回答,PostComments
应该由你具体保存,但只有当你已经保存了Post
,它准备被设置为PostComment
。当然,你应该在PostComment
中有Post
和ManyToOne
,这样你就可以这样做了。
我不知道你是否调查了相关Entities
的Query
行为,但我认为你也会发现更多的惊喜。既然我已经这样做了,我做了这些评论。
引用:
什么是"拥有方"?在ORM映射中?
37.1实体