Difference between @LazyCollection(LazyCollectionOption.FALSE) and @OneToMany(fetch = FetchType.EAGER)
Asked Answered
C

4

34

I have one doubt about "Lazy-loading". What's the difference between use of @LazyCollection(LazyCollectionOption.FALSE) and @OneToMany(fetch = FetchType.EAGER)?

In my application I use two lists, but if I use in this format:

@OneToMany(mappedBy = "consultaSQL", orphanRemoval = true, fetch = FetchType.EAGER,
        cascade = CascadeType.ALL)
private List<ParametroSQL> parametros;


@OneToMany(mappedBy = "consulta", orphanRemoval = true, fetch = FetchType.EAGER,
        cascade = CascadeType.ALL)
private List<Contato> contatos;

I have this error:

Caused by: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags

I know this occurs because the Hibernate does not allow me to loading two lists at the same time. But if I use this format:

@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(mappedBy = "consultaSQL", orphanRemoval = true,
        cascade = CascadeType.ALL)
private List<ParametroSQL> parametros;

@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(mappedBy = "consulta", orphanRemoval = true,
        cascade = CascadeType.ALL)
private List<Contato> contatos;

it works perfectly.

sorry for my English thanks

Caridadcarie answered 23/9, 2014 at 13:44 Comment(0)
M
29

The fundamental difference between the annotations is that @OneToMany and its parameters (e.g. fetch = FetchType.EAGER) is a pure JPA. It can be used with any JPA provider, such as Hibernate or EclipseLink.

@LazyCollection on the other hand, is Hibernate specific, and obviously works only if Hibernate is used.

If possible, try to stick to the JPA specification as much as possible. By doing this, you should be able to switch provider easily (at least in theory).

As for your real problem, could it be that you are using a Hibernate version that doesn't support JPA 2.0 as this answer suggests?

Mukund answered 23/9, 2014 at 14:0 Comment(1)
The problem with FetchType.EAGER that OP describes is still in Hibernate version 5.2.Dynamotor
G
1

As proposed in this post : https://mcmap.net/q/64117/-hibernate-throws-multiplebagfetchexception-cannot-simultaneously-fetch-multiple-bags Changing List by Set should solve the MultipleBagFetchException. That solved mine.

Girdler answered 13/1, 2018 at 10:52 Comment(1)
This post explains why changing to Set is not a correct solution.Monasticism
S
0

I think i got this same problem...

try on all collections...

 @Fetch(FetchMode.SUBSELECT)

It should eliminate error

Solicit answered 26/12, 2016 at 12:24 Comment(0)
R
0

There is a dedicated section of hibernate docs that explains that. Long story short - from a functional perspective, these annotations are identical (although, there is a report that this is not quite the case), or at least this is what it was meant to be.

The reason for Hibernate to create its own annotations for that is not specified, but from my experience, frameworks tend to create their annotations/solutions for some problems where they do not what to depend on a separate specification (JPA in this case) or library (simply because they have no control over the library's code), so I guess Hibernate just wanted to be more flexible in here in case it would want to add anything in lazy loading capability.

In case the link ever dies, there is an equivalence table from Hibernate docs (Table 2.3):

Annotations                             Lazy                    Fetch
@[One|Many]ToOne](fetch=FetchType.LAZY)  @LazyToOne(PROXY)      @Fetch(SELECT)
@[One|Many]ToOne](fetch=FetchType.EAGER) @LazyToOne(FALSE)      @Fetch(JOIN)
@ManyTo[One|Many](fetch=FetchType.LAZY)  @LazyCollection(TRUE)  @Fetch(SELECT)
@ManyTo[One|Many](fetch=FetchType.EAGER) @LazyCollection(FALSE) @Fetch(JOIN)

So, in the author's particular case there is indeed no difference.

Rochelle answered 24/2 at 18:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.