Como desativar o Lazy Loading do JPA

Bom dia galera,

estou criando uma aplicação desktop na qual eu quero sempre trazer tudo para a memória assim que busco.
Ou seja, não quero carga preguiçosa.

Setando o EAGER nos relacionamentos não está dando certo.

Estou setando do lado do List e ele não vai.

Tentei setar nos 2 lados, mas dá erro.

O que fazer?

ps: estou usando Hibernate

Oi Filipe

Bastante periogoso colocar tudo na memoria assim…

Mas por que nao esta funcionando so colocar o EAGER? que erro ocorre?

abracos

Um lado com EAGER:

[code]class Simulacao …

@OneToMany(cascade = CascadeType.ALL, mappedBy = “simulacao”)
private List<Compartimento> compartimentoList;

class Compartimento …

@JoinColumn(name = “simulacao”, referencedColumnName = “id”, nullable = false)
@ManyToOne(optional = false, cascade=CascadeType.ALL, fetch=FetchType.EAGER)
private Simulacao simulacao;
[/code]

Faça a busca e encontro meu objeto simulação.

Após isso tento salvar meu objeto simulação, ao fazer isso confiro se minha lista de compartimentos está vazia:

if (simulacao.getCompartimentoList() != null) {

...

}

Dá esse erro:

26/10/2009 17:39:16 org.hibernate.LazyInitializationException &lt;init&gt;
SEVERE: failed to lazily initialize a collection of role: embrapa.entity.Simulacao.compartimentoList, no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: embrapa.entity.Simulacao.compartimentoList, no session or session was closed
Hibernate: select simulacao0_.id as id11_7_, simulacao0_.clima as clima11_7_, simulacao0_.descricao as descricao11_7_, simulacao0_.nome as nome11_7_, simulacao0_.pesticida as pesticida11_7_, simulacao0_.solo as solo11_7_, clima1_.id as id0_0_, clima1_.diafin as diafin0_0_, clima1_.diaini as diaini0_0_, clima1_.evaporef as evaporef0_0_, clima1_.simulacao as simulacao0_0_, climadiali2_.clima as clima9_, climadiali2_.id as id9_, climadiali2_.id as id3_1_, climadiali2_.chuva as chuva3_1_, climadiali2_.clima as clima3_1_, climadiali2_.dia as dia3_1_, climadiali2_.evaporef as evaporef3_1_, climadiali2_.rad as rad3_1_, climadiali2_.tempmax as tempmax3_1_, climadiali2_.tempmin as tempmin3_1_, climadiali2_.umidade as umidade3_1_, climadiali2_.vento as vento3_1_, simulacao3_.id as id11_2_, simulacao3_.clima as clima11_2_, simulacao3_.descricao as descricao11_2_, simulacao3_.nome as nome11_2_, simulacao3_.pesticida as pesticida11_2_, simulacao3_.solo as solo11_2_, pesticida4_.id as id6_3_, pesticida4_.coefdeg as coefdeg6_3_, pesticida4_.coefdifu as coefdifu6_3_, pesticida4_.coefpart as coefpart6_3_, pesticida4_.eneati as eneati6_3_, pesticida4_.expfre as expfre6_3_, pesticida4_.numap as numap6_3_, pesticida4_.simulacao as simulacao6_3_, pesticida4_.tempref as tempref6_3_, pesticida4_.umiref as umiref6_3_, pesticida4_.walker as walker6_3_, simulacao5_.id as id11_4_, simulacao5_.clima as clima11_4_, simulacao5_.descricao as descricao11_4_, simulacao5_.nome as nome11_4_, simulacao5_.pesticida as pesticida11_4_, simulacao5_.solo as solo11_4_, solo6_.id as id12_5_, solo6_.altlam as altlam12_5_, solo6_.numcompartimentos as numcompa3_12_5_, solo6_.numhorizontes as numhoriz4_12_5_, solo6_.profundidade as profundi5_12_5_, solo6_.simulacao as simulacao12_5_, simulacao7_.id as id11_6_, simulacao7_.clima as clima11_6_, simulacao7_.descricao as descricao11_6_, simulacao7_.nome as nome11_6_, simulacao7_.pesticida as pesticida11_6_, simulacao7_.solo as solo11_6_ from simulador.public.simulacao simulacao0_ left outer join simulador.public.clima clima1_ on simulacao0_.clima=clima1_.id left outer join simulador.public.climadia climadiali2_ on clima1_.id=climadiali2_.clima left outer join simulador.public.simulacao simulacao3_ on clima1_.simulacao=simulacao3_.id left outer join simulador.public.pesticida pesticida4_ on simulacao3_.pesticida=pesticida4_.id left outer join simulador.public.simulacao simulacao5_ on pesticida4_.simulacao=simulacao5_.id left outer join simulador.public.solo solo6_ on simulacao5_.solo=solo6_.id left outer join simulador.public.simulacao simulacao7_ on solo6_.simulacao=simulacao7_.id where simulacao0_.id=?
        at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)
        at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350)
...
...

Caso não saiba como resolver, vou colocando as outras possibilidades …

Testei sem EAGER dá o mesmo erro. Então o EAGER não ta fazendo diferença…

E com EAGER dos 2 lados dá erro:

INFO: building session factory Exception in thread "AWT-EventQueue-0" javax.persistence.PersistenceException: [PersistenceUnit: HibernatePersistentUnit] Unable to build EntityManagerFactory at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:677) at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:126) at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:51) at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:33) at embrapa.entity.JPAUtil.&lt;init&gt;(JPAUtil.java:23) .... .... .... .... Caused by: org.hibernate.HibernateException: cannot simultaneously fetch multiple bags at org.hibernate.loader.BasicLoader.postInstantiate(BasicLoader.java:66) at org.hibernate.loader.entity.EntityLoader.&lt;init&gt;(EntityLoader.java:75) at org.hibernate.loader.entity.EntityLoader.&lt;init&gt;(EntityLoader.java:43) at org.hibernate.loader.entity.EntityLoader.&lt;init&gt;(EntityLoader.java:33) at org.hibernate.loader.entity.BatchingEntityLoader.createBatchingEntityLoader(BatchingEntityLoader.java:103)

FilipeNevola, essa coisa de lazy/eager é um assunto bem complexo. Mas vamos lá…

No seu caso porque você quer trazer tudo como eager? Você está usando Spring ou EJB? Web ou desktop?

Essa mensagem de erro que você está tendo ao colocar tudo para eager é para te proteger de “esguelar” o servidor com muitos objetos em memória. Um agravante é que você está usando bidirecional com eager. Se eu fizer uma aplicação de login, onde um usuario X permissões seja n:m. Se você usar bidirecional eager, quando você ler um usuário ele lerá todas permissões desse user, que lerá todos usuários com essas permissões, e assim vai. Quando você notar carregou toda a base de dados. É algo a se pensar e usar com cuidado.

O ideal é você inicializar apenas o que você precisa. Tenho aqui uma aplicação com EJB, e tudo é lazy. Conforme eu preciso, antes de sair do EJB carrego o que preciso e devolvo para a tela inicializado.

Minha sugestão é primeiro você ver o que você precisa deixar bi-direcional e eager.

Quanto ao erro no session or session was closed acontece quando você carrega o objeto, sai do “alcance” do entity-manager e depois volta. Vou explicar na prática. Você carrega um objeto e por na sessão. Depois de algum tempo você pega esse mesmo objeto e tenta fazer algo. O que acontece é que você não possui mais a sessão de origem aberta, assim essa exception é lançada.

Abraços

esse erro é normal… o hibernate não é capaz de fazer multiplos eagers… pq o select não suporta…

Dicas:

  • evite eagers 1-N … e mais… evite o relacionmento 1-N …

  • evite relacionamentos bi-direcionais no N-M … mapei só um lado, o proprietario da relação…

  • quando necessitar saber o resultado da outra ponta, faça uma consulta…

  • é complicado manter integridade bi-direcional, principalmente com cascade, por exemplo… vc adiciona um objeto em uma ponta… e da um marge, … em outro lugar, vc tem o mesmo objeto, e da outro marge (e o objeto que vc adicionou antes some) … isso é só um caso…

Porquê evitar relacionamentos 1-N?
Você quer dizer pra fazer sempre relacionamentos N-1?

Porquê evitar relacionamentos 1-N?
Você quer dizer pra fazer sempre relacionamentos N-1?[/quote]

O Lavieri quer dizer para mapear, por exemplo, usuario.grupo e não mapear grupo.usuarios, no caso sendo usuário (n) grupo (1).

Ou seja, você mapeia apenas no lado que realmente precisa da FK, e não o inverso.

Porquê evitar relacionamentos 1-N?
Você quer dizer pra fazer sempre relacionamentos N-1?[/quote]

O Lavieri quer dizer para mapear, por exemplo, usuario.grupo e não mapear grupo.usuarios, no caso sendo usuário (n) grupo (1).

Ou seja, você mapeia apenas no lado que realmente precisa da FK, e não o inverso. [/quote]

Entendi, mas por exemplo em um relacionamento venda-produto é aconselhavel mapear o venda.produtos ou o produto.venda? sendo produto (n) e venda (1).
Não consigo ver vantagem em mapear produto.venda. Porquê evitar o mapeamento venda.produtos?