A discussão aqui é se vale a pena usar Lazy Loading automático ou se é melhor fazer o lazy loading na mão mesmo.
Imagine um Carro que contém um object Motor dentro dele.
public class Carro {
private int id;
private String name;
private String chassi;
private int motor_id;
private Motor motor;
// getters and setters
}
public class Motor {
private int id;
private String tipo;
private String potencia;
// getters and setters
}
O conceito de Lazy Loading, dita que quando vc carregar o Carro do banco-de-dados, o Motor não será carregado imediatamente, mas apenas após o método getMotor() ser chamado por alguém.
Ou seja, se ninguém precisar do motor, o motor nunca será carregado do banco de dados.
A primeira vista isso parece ser uma coisa maravilhosa. Vc para e pensa: “Estou economizando acesso ao banco-de-dados!” Se meu carro tivesse outros 10 objetos dentro dele (lista de peças, rodas, bancos, etc), nenhum desses objetos seria carregado de primeira, ou seja, eu economizaria tempo, banco-de-dados, e a coisa seria feita sob demanda, a medida que alguém precisasse desses objetos e chamasse seu método get.
Agora vamos pensar por uma outra ótica:
-
Para a solução de ORM (Hibernate, iBatis, etc) implementar isso é necessário o uso de PROXIES. Isso porque quando alguém chamar o getMotor(), precisamos interceptar isso, fazer o load do motor, colocar o motor no Carro e retornar a execução para o método normal getMotor(). Para implementar proxies em Java vc precisa da implementação do JDK ou de CGLIB. Se for usar a implementação do JDK, o seu objeto (bean) precisa ser uma interface, ou seja, na minha opinião um preço muito grande a se pagar! Se for usar CGLIB, vc (e a jvm que for executar isso) precisa se sentir confortável com alteração de bytecode, para executar esse proxy “por trás dos panos”. Lembre-se que tudo isso tem um custo de performance, que concordo “muitas vezes” pode ser ignorado.
-
LazyLoading acaba levando a uma prática não muito boa, que é fazer acessos ao banco-de-dados enquando uma página JSP está sendo executada. O que acontecerá se uma exception for lançada ali devido a algum erro de acesso ao banco de dados. O seu framework e a sua aplicação web estão prontos para tratar isso de forma correta? Não seria melhor que todo esse trabalho sujo fosse feito na action e quando chegássemos no JSP tudo já estivesse prontinho, ou seja, o JSP é apenas uma coisa burra que pega os resultados e exibe?
-
LazyLoading exige que vc (ou o seu framework) não feche a sessão/connection até que o JSP seja completamente executado, caso contrário vc vai ganhar um LazyInstantiationException. Ou o seu framework faz isso pra vc através de um filtro, ou vc vai ter que implementar isso não mão, provavelmente através de um ServletFilter.
Diante dos pontos acima, fica a pergunta. Será LazyLoading automático realmente uma coisa necessária e maravilhosa? Não seria melhor deixamor nós de sermos Lazy (preguiçosos) e controlarmos nós mesmos quem deve ser carregado e quando?
Voltemos ao exemplo do Carro com Motor.
Se eu sei que vou fazer um forward para uma página JSP que não vai precisar do motor do carro, ou seja, vai usar apenas o carro e não as informações do motor, eu não preciso me preocupar em carregar o motor.
public String execute() throws Exception {
Carro carro = new Carro(23);
session.load(carro); // objeto motor não vai ser carregado...
output.setValue("carro", carro);
return SUCCESS;
}
E se eu sei que a minha página JSP vai precisar das informações do motor eu simplesmente carrego o motor eu mesmo: (ou quem sabe pego de um cache???)
public String execute() throws Exception {
Carro carro = new Carro(23);
session.load(carro);
Motor motor = new Motor(carro.getMotorId());
session.load(motor);
carro.setMotor(motor);
output.setValue("carro", carro);
return SUCCESS;
}
A questão para debate é:
Precisamos realmente de LazyLoading automático ou devemos deixar de ser lazy (preguiçosos) e fazer nós mesmos esse controle de “quem é carregado, quando e onde”? Vc já teve problema com LazyInstantiationException?