Vale a pena retornar objetos gerenciados no DAO?

Pessoal, estava numa pequena discussão aqui no trabalho e estávamos conversando sobre a real necessidade de retornar objetos gerenciados no DAO ou não. Quais as vantagens, desvantagens, etc. Havia uma situação aqui em que um objeto gerenciado era retornado por um método de uma classe DAO, mas ao chegar na apresentação, somente dois atributos desse objeto eram utilizados. Nessa discussão, surgiram algumas perguntas:

Será mesmo necessário alocar aquele objeto inteiro na memória uma vez que utilizaremos somente dois atributos dele?
Retornar o objeto gerenciado não predispõe outras camadas a utilizar os métodos gets() gerando mais selects desnecessários que poderiam ter sido feitos todos de uma vez só no DAO?
Não é melhor retornar uma lista de arrays de Objects contendo somente as informações que serão utilizadas de fato?
Por outro lado, se eu vou retornar somente o que é necessário naquele momento e não vou utilizar os benefícios do ORM, por que estou utilizando JPA então?

cara, eu dou consultoria de desempenho e muitas vezes, sugiro a solução de voltar a usar o bom e velho jdbc pra alguma operação específica de um sistema que estou analisando, sempre tem resistência no começo mas depois de uma prova de conceito, o pessoal acaba incorporando a solução ao produto.
o que eu acho disso é que deve se pensar no propósito do seu sistema, como ele vai ser usado, modelar a arquitetura para suportar o uso proposto, e depois definir os frameworks.

Bom, primeiro vocês não deveriam estar usando o DAO, mas isso é outra discussão!

Depende! Primeiro é necessário lembrar que uma consulta ao banco de dados é algo custoso, por padrão deve-se sempre buscar todos os dados de na primeira consulta. Normalmente é melhor que executar duas consultas. Se o objeto utiliza outros objetos é necessário avaliar a carga tardia desses objetos para se evitar muitos joins, caso esses objetos tenham pouco acesso isso pode justificar uma segunda chamada ao banco! Um exemplo é os dados de um cliente que tenha um objeto separado para o endereço. Se o endereço é pouco utilizado deve-se fazer um lazy loading. Mas não existe problema em trazer todos os outros campos do cliente.
A questão de manter o objeto gerenciado é relativa! Você pode liberar o objeto assim que o utilizar em um contexto de sessão, por exemplo, caso não vá mais utiliza-lo. No contexto de uma única requisão não faz diferença, pois a memória vai ser liberada ao final dessa.

Sim, conforme foi dito antes é questão de se avaliar. Normalmente é melhor realizar uma única consulta! Mas se o objeto é composto por outros objetos que não são pouco utilizados talves seja melhor realizar uma carga tardia.

Bom, ai OO vai para o saco e essa nunca é uma boa escolha.

Na verdade o problema é maior do que ORM. Para que você está usando objetos? Se o problema for desempenho você pode até criar uma camada de mapeamento simples e utilizar JDBC, mas isso normalmente é exceção e não regra. Nesse caso você carrega e o ID e todos os outros campos podem ser carregados utilizando carga tardia!

Concordo com o Xandy, eh tudo uma questão de avaliação caso a caso. Eu, quando preciso, deixo de lado o Hibernate e faço consultas diretas com JDBC. Se for só pela questão conceitual, trazer mais algumas colunas ou não é irrelevante, não valeria nem a criação do tópico.

Até porque como já foi dito, você manda OO pro espaço. Aí é questão de avaliar se vale ou não a pena em cada caso.

[quote=x@ndy]

Na verdade o problema é maior do que ORM. Para que você está usando objetos? Se o problema for desempenho você pode até criar uma camada de mapeamento simples e utilizar JDBC, mas isso normalmente é exceção e não regra. Nesse caso você carrega e o ID e todos os outros campos podem ser carregados utilizando carga tardia![/quote]

Eu sonho com o dia em que eu possa escrever sql e ele seja “magicamente” transformado em objetos de negocio. Não gosto de hql, não gosto do Hibernate, mas tenho (ainda) que conviver com ele. Tenho até algumas ideias para o problema, baseadas no MentaBean do saoj, mas ainda não tive tempo/disposição pra começar a mexer.

Uma idéia é fazer o q o Hibernate faz usar reflection / introspecão e anotações para informar no bean o nome da tabela, o nome de cada coluna q representa cada atributo, qual é o atributo id. Basicamente o q o Hibernate faz.

[]s

Uma idéia é fazer o q o Hibernate faz usar reflection / introspecão e anotações para informar no bean o nome da tabela, o nome de cada coluna q representa cada atributo, qual é o atributo id. Basicamente o q o Hibernate faz.

[]s[/quote]

Eh mais ou menos o que eu estou pensando em fazer, mas escrevendo sql ao inves de hql.

Estou fazendo algo parecido para um cliente, via reflection / introspection grava um tipo de log / auditoria.
E usando o mesmo recurso já fiz para o delete.
Já tenho uma idéia para montar fazer o restante, insert, update e select.

[]s

[quote=fabiophx]Estou fazendo algo parecido para um cliente, via reflection / introspection grava um tipo de log / auditoria.
E usando o mesmo recurso já fiz para o delete.
Já tenho uma idéia para montar fazer o restante, insert, update e select.

[]s[/quote]

Acho que para insert e update o MentaBean já me resolve, o que eu queria mesmo era escrever um sql e obter objetos de negócio, sem nada de proxy, lazy e sei la mais o que. Se o cara trouxer so id e razao social e tentar acessar o cnpj toma um nullpointer na cabeça. Sem problemas, se ali ele precisar do cnpj ele acrescenta no sql.

Mas eh exatamente o que voce disse, eh basicamente o que o hibernate faz, mas partindo do sql.

Uma idéia é fazer o q o Hibernate faz usar reflection / introspecão e anotações para informar no bean o nome da tabela, o nome de cada coluna q representa cada atributo, qual é o atributo id. Basicamente o q o Hibernate faz.

[]s[/quote]

Eh mais ou menos o que eu estou pensando em fazer, mas escrevendo sql ao inves de hql.[/quote]
É por ai, sem bala de prata, sem purismos ou preciosismos exagerados, com Hibernate use Named native SQL para o caso de relatorios e consultas complexas. E nunca engesse nada, deixe a “session” do ORM com possibilidade de ser acessada, nao tratando o desenvolvedor como criança.

Também acho sql uma ótima dsl para manipulação de dados, mas vendo o LINQ do .NET eu comecei a ver um substituto a altura.

Mesmo para cargas parciais, com o recurso de tipos anônimos, ele cai muito bem, na minha opinião.

Também acho sql uma ótima dsl para manipulação de dados, mas vendo o LINQ do .NET eu comecei a ver um substituto a altura.

Mesmo para cargas parciais, com o recurso de tipos anônimos, ele cai muito bem, na minha opinião.

[/quote]
Concordo, é outro patamar, Java tem planos para chegar lá. O que uso mais no .NET é QueryOver do NHibernate, que é limpo como o LINQ mas bem mais flexível e robusto. Só que relatorios bizarros (SQLs gigantes, que as vezes tem até tabelas de outros sistemas) uso named native SQL mesmo.