Setar Objetos na sessão, uma boa prática?

Pessoal,
Estou em dúvida quanto a forma que tenho utilizado para guardar certos dados do usuário, darei a situação que tive no meu projeto:
O usuário logava e no decorrer do sistema eu precisava pegar vários dados desse usuário, seja o login, seja o endereço(por exe…), em fim eu tinha duas alternativas, ou guardava o Objeto usuário na sessão para recuperá-la quando preciso ou guardava apenas o login e fazia a query trazendo só o necessário… optei por guardar apenas o login e a medida que fosse precisando de algo fazia a query e trabalhava o dado que necessitava, mas ainda assim estava guardando uma string na sessão.
Minha dúvida é: é correto guardar objetos na sessão? isso pode acarretar algum problema de desempenho?
E estando isso errado, qual a melhor forma de se trabalhar? Guardando o mínimo possível e fazendo uma consulta para obter o restante dos dados sempre que necessário?

Tem que analisar o caso…

Se você vai consultar o banco de dados toda hora para puxar o que não está na sessão… pode ser interessante manter o dado na sessão para a aplicação ter melhor performance.

Não está errado guardar objetos na sessão mas o ideal é que realmente se guarde o mínimo.

Não sei lhe precisar se é uma boa prática ou não, mantêr objetos de sessão, mas um tempo atrás, eu me deparei com um implementação muito interessante. Algo como:

EntityManager entityManager = this.factory.createEntityManager();
request.setAttribute("entityManager", entityManager);

… dessa forma disponibilizando uma EntityManager nos MB, ou sejá lá onde deus quiser!

[]'s

“interessante”… voce foi gente boa né?! eheheheh

Zoado? Muitas conexões?

Mas detalhe, é Filtro, esse exemplo foi retirado da apostila da caelum, segue a classe completa:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package filtros;

import java.io.IOException;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;



/**
 *
 * @author HOUSE
 */
//@WebFilter(servletNames = {"Faces Servlet"})
public class JPAFilter implements Filter {

    private EntityManagerFactory factory;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {

        EntityManager entityManager = this.factory.createEntityManager();
        request.setAttribute("entityManager", entityManager);


        entityManager.getTransaction().begin();

        chain.doFilter(request, response);

        try {
            entityManager.getTransaction().commit();
        } catch (Exception e) {
            entityManager.getTransaction().rollback();
            throw new ServletException(e);
        } finally {
            entityManager.close();
        }
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.factory = Persistence.createEntityManagerFactory("copadomundo");

    }

    @Override
    public void destroy() {
        this.factory.close();
    }
}

Bem… não gostei muito dessa estratégia de colocar um entityManager no request não…

É a mesma coisa que colocar uma conexão JDBC na requisição…

Deve ser uma implementação de Open Session In View (se nao estou enganado é esse o nome do design pattern)

Esse pattern tem até algumas criticas relativas a consumo de recursos…

[quote=rogelgarcia]Bem… não gostei muito dessa estratégia de colocar um entityManager no request não…

É a mesma coisa que colocar uma conexão JDBC na requisição…

[/quote]

Entendi rogelgarcia,

Obrigado pelo esclarecimento!

[]'s

mas então, gente, ideal é guardar o mínimo ou mesmo n guardar nada na sessão?
vamos dizer que entre diversas consultas ao banco e manter um dado na sessão é preferível ter o dado na sessão?
mas isso causa perda de performance? como isso é normalmente feito em aplicação que suportam grande número de usuários, aqui no GUJ por exemplo?
digo isso porque sou severamente criticado pelos meus colegas de trabalho toda vez que falo em guardar um valor na sessão…
é como se guardar algo na sessão fosse um POG… honestamente não penso assim, mas gostaria de fato de saber se é uma boa prática e caso n sendo que tipo de risco pode trazer para a aplicação.
obrigado.

Bem… o ideal é guardar o mínimo na sessão… mas o login por exemplo é uma informação bem usual de se guardar…

[quote=gambazinho]mas então, gente, ideal é guardar o mínimo ou mesmo n guardar nada na sessão?
vamos dizer que entre diversas consultas ao banco e manter um dado na sessão é preferível ter o dado na sessão?
mas isso causa perda de performance? como isso é normalmente feito em aplicação que suportam grande número de usuários, aqui no GUJ por exemplo?
digo isso porque sou severamente criticado pelos meus colegas de trabalho toda vez que falo em guardar um valor na sessão…
é como se guardar algo na sessão fosse um POG… honestamente não penso assim, mas gostaria de fato de saber se é uma boa prática e caso n sendo que tipo de risco pode trazer para a aplicação.
obrigado.[/quote]
Acredito que no seu caso, poderia ser criado um sistema de cache de objetos, caso as informações não precisem ser 100% dinâmicas na view. Um sistema fica atualizando esse cache em back-ground e assim você não fica inundando sua sessão nem acessando a base todo momento.

[quote=rogelgarcia]Bem… não gostei muito dessa estratégia de colocar um entityManager no request não…

É a mesma coisa que colocar uma conexão JDBC na requisição…

Deve ser uma implementação de Open Session In View (se nao estou enganado é esse o nome do design pattern)

Esse pattern tem até algumas criticas relativas a consumo de recursos… [/quote]
Eu criticaria esta solução somente se ficar abrindo a transação em toda requisição. Mas para evitar isto, pode-se ter um outro filtro que é utilizado nas actions que precisam da transação. E nas actions que não precisam de transação, o filtro apenas carrega o EM sem transaction aberta.

Até gosto desta abordagem, pois centraliza o gerenciamento do recurso. Não vejo diferença ter um EM no escopo do filtro ou no método da action no controller.
O único problema que vejo nesta abordagem é que se o método faz um processamento demorado (como I/O), realmente uma conexão (ou até uma transação) ficará aberta com o BD até o termino da requisição.