33

I have a many to many relationship at my Java beans. When I use List to define my variables as like:

@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;

I get that error:

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

When I use Set everything seem to work well.

I want to ask that when using many to many relationships which one to use for logical consept List or Set (because of list may have duplicates and set but what about performance and other issues)?

kamaci
  • 72,915
  • 69
  • 228
  • 366

3 Answers3

75

From relational databases perspective this is a set. Databases do not preserve order and using a List is meaningless, the order in them is unspecified (unless using so called indexed collections).

Using a Set also has great performance implications. When List is used, Hibernate uses PersistentBag collection underneath which has some terrible characteristics. I.e.: if you add a new relationship it will first delete all existing ones and then insert them back + your new one. With Set it just inserts the new record.

Third thing - you cannot have multiple Lists in one entity as you will get infamous cannot simultaneously fetch multiple bags exception.

See also:

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • Beside many to many relationship(one-one, many-one, one-many) should I use `Set` instead of `List` too for a good design pattern? – kamaci Nov 17 '11 at 21:45
  • Yes, because `List` suggests that items are ordered which is not true. I know, I know it has slightly easier API. – Tomasz Nurkiewicz Nov 17 '11 at 21:48
  • 3
    both voting up accepting as answer for detailed information and good links. – kamaci Nov 17 '11 at 21:50
  • I want to ask just to make it more clear. When I remove just one element at using List with indexed columns does remove just one (as like Set) or removes all and insert all except that removed element? – kamaci Nov 17 '11 at 22:09
  • If you are using **indexed** collection (index column), only single DELETE will occur. I think the second link has pretty good explanation of that. – Tomasz Nurkiewicz Nov 17 '11 at 22:11
  • Last question to understand whole things. What is the difference between using Set and Indexed List for both database and Java side performance and etc. Same or not? – kamaci Nov 17 '11 at 22:14
  • They are different from a database perspective. `Set` maps directly to relational databases' many-to-many relationship. Indexed `List` on the other hand requires an extra column in join table but allows you to preserve order within the relationship. Often useful. – Tomasz Nurkiewicz Nov 17 '11 at 22:19
3

How about the uniqueness requirement from Set? Doesn't this force Hibernate to retrieve all objects each time one is added to the collection to make sure a newly added one is unique? A List wouldn't have this limitation.

Marc
  • 6,773
  • 10
  • 44
  • 68
  • 1
    List has also this limitation, because hibernate needs to preserver order in Lists, so it also has to retrieve all items – Ondrej Bozek Oct 28 '15 at 21:02
0

I know the question was made years ago but I wanted to comment on this topic, just in case someone is doubtful about the set vs list issue.

Regarding lazy fetching, I think a bag (list without index) would be a better option due to the fact that you avoid retrieving all objects each time one is added to the collection to:

  • make sure a newly added one is unique, in case you are using a set
  • preserve order, in case you are using a list (with index)

Please correct me if I'm mistaken.

onofricamila
  • 930
  • 1
  • 11
  • 20