Hibernate多对多关系中使用Set还是List?

35

我有一个Java bean中的多对多关系。 当我使用List定义我的变量时,如下所示:

@Entity
@Table(name="ScD")
public class Group extends Nameable {

    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.EAGER)
    @JoinColumn(name="b_fk")
    private List<R> r;
    //or
    private Set<R> r;

我遇到了这个错误:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor#0'
...

当我使用Set时,一切似乎都很顺利。

我想问的是,在使用多对多关系时,为了逻辑概念应该使用哪个,List还是Set(因为列表可能有重复项,而集合呢?但是考虑到性能和其他问题呢)?

3个回答

78

从关系数据库的角度来看,这是一个集合。数据库不保留顺序,使用List没有意义,其中的顺序未指定(除非使用所谓的索引集合)。

使用Set也有很大的性能影响。当使用List时,Hibernate在其下使用PersistentBag集合,具有一些可怕的特点。例如:如果添加新关系,它将首先删除所有现有关系,然后将它们插回去加上新插入的。使用Set只需要插入新记录。

第三件事-您不能在一个实体中拥有多个List,因为您会遇到臭名昭著的无法同时获取多个包异常。

另请参见:


是的,因为“List”暗示了项目是有序的,但这并不是真的。我知道,我知道它具有稍微更简单的API。 - Tomasz Nurkiewicz
3
投票和接受答案都可以获得详细信息和好的链接。 - kamaci
我想问一下,只是为了更清楚。当我使用带有索引列的List删除一个元素时,它会像Set一样只删除一个吗?还是会把所有元素都删除并重新插入除被删除元素外的所有元素? - kamaci
如果您正在使用索引集合(索引列),则只会发生单个DELETE。我认为第二个链接对此有很好的解释。 - Tomasz Nurkiewicz
最后一个问题来了解整个事情。在数据库和Java方面的性能等方面,使用Set和Indexed List有什么区别?是相同的吗? - kamaci
显示剩余2条评论

3
Set对唯一性的要求如何处理?这是否会强制Hibernate每次添加对象时检索所有对象,以确保新添加的对象是唯一的?而List则没有此限制。

1
列表也有这个限制,因为Hibernate需要保留列表中的顺序,所以它也必须检索所有项目。 - Ondrej Bozek

0

我知道这个问题是几年前提出的,但我想在这个话题上发表评论,以防有人对集合和列表的问题有疑问。

关于“懒加载”,我认为一个没有索引的(列表)会是更好的选择,因为你可以避免每次添加到集合中时都检索所有对象:

  • 确保新添加的对象是唯一的,如果你使用集合的情况下
  • 保留顺序,如果你使用列表的情况下(有索引)

如果我说错了,请纠正我。


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