Melhor maneira para se trabalhar com relacionamentos JPA + Hibernate

Aew galera

Estou com uma duvida no JPA, estou desenvolvendo para Desktop, onde duas aplicações acessam o mesmo banco de dados simultaneamente, por isso nao posso utilizar o cache de 1 nivel do Hibernate, e para atualizar os meus selects eu estou dando um clear sempre no inicio dos metodos de select no meu GenericDAO, mas assim gera um problema pois tenho por exemplo um objeto NFiscal com varios relacionamentos que sao populados com LAZY, mas em um mesmo instante do codigo preciso dar um select para pegar a NFiscal e outro objeto a partir dae perco a sessao e nao consigo pegar os objetos relacionados com NFiscal

Por exemplo
Aqui populo meu objeto NFiscal

nFiscal = nFController.getNFiscal(empresa, new Float(dfrm.getTxtNFNumber().getText()), dfrm.getTxtSerie().getText(), empresa.getCgc());
e logo abaixo

estados = estController.getByUF(nFiscal.getCliente().getClientesConsult().getUf());

depois disso se eu tentar buscar

por exemplo vai me gerar uma Exception pois eu dei um clear na sessao ao buscar estados e o relacionamento esta com Lazy

O que voces me recomendam a melhor pratica de programaçao para resolver esse problema, passar a utilizar EAGER (mas assim em casos que funcionaria normalmente com Lazy, e que nao precisaria popular todos relacionamentos vou ter perda de desempenho) nos relacionamentos, continuar com LAZY mas chamar os getObjeto que vou precisar e assim executar os selects e popular objetos auxiliares…?

Segue um metodo de busca no meu GenericDAO

protected <T extends Serializable> T getPurePojo(String query, Object[]... parametros) { em.clear();//aqui me zera a sessao e gera todo o problema Query qr = em.createNamedQuery(query); for (Object[] param : parametros) { qr.setParameter(param[0].toString(), param[1]); } Object retorno = qr.getSingleResult(); return (T) retorno; }

Obrigado.

A primeira coisa eh remover o “clear” de dentro destes metodos. Pode parecer correto fazer isso dentro do DAO, mas no seu caso, vc precisa de alguem numa camada acima para coordenar esta limpeza.

Dependendo da frequencia que vc espera que os seus usuarios atualizem um mesmo registro, vc pode tanto dar um refresh no objeto antes de mostra-lo na tela ou vc pode utilizar um metodo de optimistic locking e dar um catch na excecao quando houver uma tentativa de atualizacao em um registro “velho”.

ja tentei utilizar o refresh no objeto mas isso gera uma perda de desempenho maior ainda pois uma lista de 1000 registros de NFiscal por exemplo pra cada refresh ele varre todos os relacionamentos e popula como se fosse por EAGER os objetos, a melhor maneira que encontrei ate agora foi chamar o remove e passar null como parametro e tratar a excessao com isso nao perco qse nada de desempenho e minha sessao fica aberta normalmente e o cache de 1 nivel fica limpo.

Agora sobre optimistic locking vou dar uma pesquisada pois nunca vi nada sobre o assunto, se tiver como me passar algumas informações agradeço.

Obrigado.

Agora fiquei curioso… Pq vc esta usando “clear”? Como prevencao de problemas, ou pq vc realmente precisa?

fiz como voce me falou tratei o clear na sessao um nivel acima dentro do meu DaoImp ao buscar nota limpo a sessao ja em estados nao limpo a sessao, vou fazer testes, aqui eu uso o Entity + Dao + Service no meu dao tenho total acesso ao EntityManager pois dou extends em GenericDao, demorei pra perceber mas esse clear na sessao nao é generico e nao deve ficar em GenericDao…

finalizando os testes eu posto o resultado…

Entao eu uso o clear pois varias aplicações acessam o banco simultaneamente, e se eu nao dou um clear, refresh ou alguma transação de insert, update ou remove o hibernate guarda os valores dos objetos em cache de 1 nivel e assim nao consigo pegar as alterações no banco de dados feitas por outras aplicações, como por exemplo uma mudança de status em uma NFiscal quando dou o select ele popula pelo cache de 1 nivel assim nao tenho os valores reais

agora funcionou certo tratando o clear no Dao (1 nivel a cima)

mas estou curioso para aprender mais alternativas como voce disse

Obrigado.