JPA 2中的List与Set - 优缺点及方便性

5
我已经在Stack Overflow和其他网站上搜索了关于使用 Sets vs Lists 的优点、缺点和方便之处,但我真的找不到一个明确的答案来确定何时使用这个或那个。
从Hibernate的文档中可以看出,非重复记录应该放入Sets中,然后对每个可能被包装成Set的实体实现它的hashCode()和equals()。但是,对于方便和易用性的价格,有一些文章建议使用商业键作为每个实体的ID,然后无论对象的状态如何(管理的、分离的等),都可以完美地实现hashCode()和equals()。
这都没问题...直到我遇到很多情况,使用Sets就根本行不通,比如排序(虽然Hibernate给你SortedSet的想法),集合对象.get(index)、集合对象.remove(int location || Object obj)、Android的ListView/ExpandableListView的架构(GroupIds,ChildIds)等等。我的观点是:Sets很难操作,使其100%工作也很困难。
我很想把我的项目中的每个集合都改成List,因为它们的工作效果很好。我所有实体的ID都是通过MYSQL的自动生成序列生成的(@GeneratedValue(strategy = GenerationType.IDENTITY))。
有没有人能够明确地解决我上述所有细节的疑问?
此外,是否可以使用Eclipse自动生成hashCode()和equals()来为每个实体的ID字段创建这些方法? 在每种情况下都会有效吗?
谢谢你,
Renato

List和Set与JPA2关系不大,它取决于你的应用程序需要什么。JPA2可以同时处理两者。 - Neil Stockton
ID在大多数情况下不是业务键,而是合成键。因此,对于您最后的问题,答案是否定的,因为这样做是错误的。Neil已经回答了关于List v Set的问题。 - Vlad
2个回答

4
List versus Set

允许重复项 列表(List)允许重复项,而集合(Set)不允许重复项。对于某些人来说,这可能是选择列表或集合的主要原因。

多个Bag异常 - 单次查询中多个Eager加载 Hibernate处理的一个显著差异是,您不能在单个查询中获取两个不同的列表。它会抛出一个"cannot fetch multiple bags"异常。但是使用集合就没有这样的问题。


好的回答,但是Xstian的回答更完整。谢谢。 - renatoaraujoc

3
如果没有指定索引列,列表将被Hibernate视为一个包(没有特定的排序)。
@OneToMany
@OrderBy("lastname ASC")
public List<Rating> ratings;

Hibernate处理中的一个显著差异是,您不能在单个查询中获取两个不同的列表。例如,如果您有一个Person实体,其中包含联系人列表和地址列表,您将无法使用单个查询加载所有联系人和地址的人员。在这种情况下的解决方案是进行两个查询(避免笛卡尔积),或者至少为其中一个集合使用Set而不是List。
当您必须在实体上定义equals和hashCode并且没有不可变的函数键时,使用Hibernate使用Set通常很困难。
此外,我建议您查看此link

1
您提供的链接提供了关于Set vs List困境的优秀信息。但是,您能否为我提供有关mysql主键生成和hashCode和equals的正确实现的一些见解?此外,我将接受您的答案作为正确答案。谢谢。 - renatoaraujoc
@Renatinn 很高兴能够帮助你 :) .. 无论如何,我建议你查看另一个链接,它解释了hashCode和equals的正确实现方式 :) - Xstian
1
这个答案只是从另一个问题(https://dev59.com/TWw15IYBdhLWcg3whME1#6563037)复制过来的吗? - Dominic
https://dev59.com/TWw15IYBdhLWcg3whME1. 致力于 - Samy Omar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接