我认为使用集合或列表的问题要困难得多。至少当您使用休眠作为 JPA 实现时。如果您在休眠状态下使用List,它会自动切换到“Bags”范式,其中可以存在重复项。
该决策对查询休眠执行有重大影响。下面是一个小例子:
有两个实体,员工和公司,典型的多对多关系。为了将这些实体相互映射,存在一个JoinTable(我们称之为“employeeCompany”)。
在两个实体(公司/员工)上选择数据类型列表
因此,如果您现在决定从 CompanyXY 中删除 Employee Joe,则休眠将执行以下查询:
delete from employeeCompany where employeeId = Joe;
insert into employeeCompany(employeeId,companyId) values (Joe,CompanyXA);
insert into employeeCompany(employeeId,companyId) values (Joe,CompanyXB);
insert into employeeCompany(employeeId,companyId) values (Joe,CompanyXC);
insert into employeeCompany(employeeId,companyId) values (Joe,CompanyXD);
insert into employeeCompany(employeeId,companyId) values (Joe,CompanyXE);
现在的问题是:为什么休眠不仅执行该查询?
delete from employeeCompany where employeeId = Joe AND company = companyXY;
答案很简单(Nirav Assar在他的博客文章中有很多):它不能。在袋子的世界里,全部删除并重新插入所有剩余是唯一正确的方法!阅读该内容以获取更多说明。http://assarconsulting.blogspot.fr/2009/08/why-hibernate-does-delete-all-then-re.html
现在得出一个大结论:
如果您在员工/公司 - 实体中选择“集”而不是“列表”,则不会遇到该问题,并且只执行一个查询!
为什么呢?因为休眠不再处于包的世界中(如您所知,Sets不允许重复),并且现在只能执行一个查询。
因此,List和Sets之间的决策并不是那么简单,至少在查询和性能方面是这样!