我有两个实体:UserAccount
和Notification
. 它们具有如下所示的关系。
public class UserAccount {
@Id
@Column(name = "USER_NAME")
private String emailId;
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name = "USERS_NOTIFICATIONS", joinColumns = { @JoinColumn(name = "USER_NAME") }, inverseJoinColumns = { @JoinColumn(name = "NOTIFICATION_ID") })
private List<Notification> notifications;
//setters, getter, equals and hashcode
}
两者equals()
和hashcode()
都被覆盖(由带有业务键/主键的 IDE 生成)。
给定 a UserAccount
,当我添加第一个 时Notification
,它会产生一个 INSERT 语句。但是在进一步添加相同的UserAccount
内容时,它首先删除然后插入:
Hibernate: delete from USERS_NOTIFICATIONS where USER_NAME=?
Hibernate: insert into USERS_NOTIFICATIONS (USER_NAME, NOTIFICATION_ID) values (?, ?)
Hibernate: insert into USERS_NOTIFICATIONS (USER_NAME, NOTIFICATION_ID) values (?, ?)
Hibernate: insert into USERS_NOTIFICATIONS (USER_NAME, NOTIFICATION_ID) values (?, ?)
//as many inserts as the notifications the user has
每个UserAccount
. 如果我将 替换为List
,Set
则会发生正常的 INSERT。在阅读了这个文档和博客后,我找到了原因。
来自文档的观察
- 在单向
@OneToMany
关联中,Set
是首选。
应该清楚的是,索引
Collections
并Sets
允许在添加、删除和更新元素方面进行最有效的操作。
- 在双向
@OneToMany
关系(@ManyToOne
管理)中,List
并且Bags
是高效的。
Bags
和Lists
是最有效的逆Collections
。
话虽如此,哪个更可取:
单向映射中的a
Set
过a ?List
@OneToMany
或者,我是否必须通过添加双向关系来使用 a 来调整我的域模型
List
,尤其是当有重复项时?