Bom, eu coloquei lazy = true nos relacionamentos.
Isto fez melhorar bastante a performance.
Então, comecei a usar o Hibernate.initialize(obj) para iniciar as collections
dentro do método get.
Ex.:
Company tem uma List de users.
então, dentro de company eu tenho um getUsers() que
está assim:
List getUsers() throws HibernateException
{
Hibernate.initialize(users);
return users;
}
Mas quando eu preciso, num Action do Struts, vai dar
LazyInitializationException.
Então eu tava vendo na documentação que daí usa-se o
Hibernate.initialize(…) para a collection.
Onde eu coloco este?
Ou é o usuário que está usando o DAO que deve colocar?
nao é sempre que vc vai mostrar isto na tela correto? Vão existir lugares em que vc vai querer que seja lazy. Entao deixe no dao, ou nao própria Action do Struts, classe de negócios sei lá.
O problema é que não se pode fechar a session sem antes ter inicializado tudo, se implementar este pattern nao precisa fazer o initialize http://www.hibernate.org/43.html, pois a session é fechada depois que sua view estiver terminada.
O probleminha é que eu criei uma estrutura (já está praticamente tudo pronto) onde cada método abre e já fecha a session.
Na verdade, algumas vezes não sou nem eu quem controla isso,
pois criei uma classe que abstrai toda abertura e fechamento de Sessions.
Ricardo, não entendi o seguinte, vc disse isso por que é redundante ou por que uma coisa é contraria a outra? Eu li em outro post aqui do GUJ que se vc usasse ThreadLocalSession não seria possivel usar lazy. No fim das contas não entendi bem, mas, então, se eu usar o initialize, a collection vai ser carregada apenas quando eu precisar tambem?
e o Session vc pegava de um ThreadLocal ou do Open Session in View?[/quote]
Veja o código do site:
public class Persistance implements Filter
{
/**
* Holds the current hibernate session, if one has been created.
*/
protected static ThreadLocal hibernateHolder = new ThreadLocal();
ThreadLocal : retornar sempre a mesma session para uma request. Se em uma request vc chamar 10 DAO´s e vários métodos nestes DAO´s, vc terá usado apenas uma session session.
Open Session in View: Não fechar a Session na Action. Quando vc enviar para o JSP/velocity sua session vai estar aberta ainda. Isto é feito com um filtro, ou com um interceptor do WebWork. (ta aí uma das coisas que eu gosto nele)…
Vc somente vai usar o inicialize em casos como o do tads (“LazyInitializationException”). Isto acontece pq quando se tenta inicializar uma collection quando a session está fechada. Devido a isso agente pede para o Hiberante inicializar antes de fechar a Session. Mas como vc pode usar este relacionamento em outras áreas do sistema, é melhor deixar o lazy=true no xml.
Pode sim.
Nao.
-> laxy=true: só carrega quando vc usar
-> initialize: força o Hiberante a carregar uma collection com lazy=true ou um proxy.
e o Session vc pegava de um ThreadLocal ou do Open Session in View?[/quote]
No sistema que fiz em Struts não usei o Open Session in View. Quando eu precisava eu fazia o inicialize igual vc. Tinha uma classe abstrata que controlava as transações.
Porém muitas vezes eu usava queries com o “fetch” para inicializar um objeto. Assim eu já forçava a inicialização no momento da query, evitando aquele Hiberante.inicialize() chato…
Em outro que usei o WebWork fiz um interceptor e o Open Session in View foi feito automaticamente. Resultado, nunca precisei fazer o inicialize O interceptor que gerenciava as transações.
cara, desculpa levantar o tópico tanto tempo depois mas eu estava procurando algumas coisas sobre paginação e vi este tópico… estou usando ww + hibernate + velocity…
ricardo, implementando do jeito que vc falou, o que vc faria para saber a quantia de registros que a query iria retornar? desculpe se a resposta for um simples count(*)… o que quero é exatamente saber se existe outro modo melhor…
é que preciso saber a quantidade de páginas totais, e para isso necessito saber quantos registros seriam retornados… não quero pegar todos os registros da consulta prá mostrar uma dúzia na tela e cada vez que o cara trocar de página buscar tudo de novo…
em primeiro lugar obrigado pela resposta!
em segundo lugar, o assunto já está totalmente fora do título do tópico… foi mal, mas acho que não precisa abrir outro tópico…
e agora ao que interessa:
como fica o desempenho com este count(*)?
acredito que deste jeito de menos i/o que selecionar tudo sempre, mas ainda resta a dúvida…
neste seu exemplo, ficaria +/- isso:
1º - seleciona os registros e joga num list;
2º - faz um filter com o list para pegar o count;
é isso?
por ex, seleciona os 10 primeiros depois faz um filter(list, “count”) prá retornar o total?