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

Gilvan André picture Gilvan André · Sep 23, 2014 · Viewed 17.6k times · Source

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

Answer

Magnilex picture Magnilex · Sep 23, 2014

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?