Controlando Cache Level 2 no Hibernate

Olá pessoal,
entrei no fórum agora e já estou querendo tirar dúvidas, heheheh.

Imaginem a seguinte situação:
Possuo um sistema Cliente/Servidor utilizando Hibernate (com uma única sessão por cliente e uma única região de cache).
O cliente X acessa o objeto, carrega em cache.
O cliente Y acessa o objeto, carrega em cache, altera e persiste ele.
O cliente X acessa o objeto novamente, mas vem sem as alterações que o Y fez, pois busca o objeto do cache.

Como posso resolver esse problema, sem que haja a necessidade de limpar todo o cache da sessão, ou finalizar a sessão e iniciar uma nova, pois isso me causaria a perda da propriedade lazy de vários outros objetos já carregados.

A idéia seria tirar apenas um objeto do cache, para forca a recarga dele à partir do banco. Ou melhor ainda, sincronizar ele com o banco.

Você precisa de um cache distribuido para isso funcionar. Além do que, ate a transação não for comitada na ponta que alterou o objeto ele não vai aparecer modificado no cache.

Na boa, largue pra lá esse negócio de uma única sessão porque isso é tiro no pé. As sessões devem ser tão curtas quanto possível, de preferência do mesmo tamanho das transações do sistema, pra evitar esse tipo de coisa.

E isso não é problema do cache de nível 2 não, é do cache de nível 1, da própria sessao. Mesmo quando você faz um “save|update|delete” em um objeto, não é garantido que a alteração vai se feita na mesma hora, o Hibernate só envia a alteração para o banco de dados “no último momento”, o que significa que você vai ter milhares de outras dores de cabeça se continuar a trabalhar desse jeito.

Facilite a sua vida e simplifique o seu trabalho.

Como ficariam meus atrubutos lazy? o “link” deles com os valores estão guardados no cache? se eu abrir e fechar as sessões eles serão perdidos, não terei como acessar eles.

Como ficariam meus atrubutos lazy? o “link” deles com os valores estão guardados no cache? se eu abrir e fechar as sessões eles serão perdidos, não terei como acessar eles.[/quote]

Basta fazer um “refresh()” neles. Mas não é uma boa idéia guardar objetos entre sessões diferentes, porque eles podem sempre estar desatualizados.

Como ficariam meus atrubutos lazy? o “link” deles com os valores estão guardados no cache? se eu abrir e fechar as sessões eles serão perdidos, não terei como acessar eles.[/quote]

Basta fazer um “refresh()” neles. Mas não é uma boa idéia guardar objetos entre sessões diferentes, porque eles podem sempre estar desatualizados.[/quote]
Mas para fazer o refresh() preciso de uma sessão.
Minha dúvida agora é: como o hibernate tem acesso aos atributos lazy de um objeto, que foi carregado à partir de uma sessão que não existe mais?
E mesmo se o Hibernate souber como fazer para buscar esses atributos, como vou saber quando preciso executar o refresh(), já que não sei quando estarei usando um atributo ainda não carregado.

Quem configura o lazy é você, se você não colocar nada no relacionamento, ele é “lazy=true”, então você já tem como saber se o seu objeto precisa ser recarregado ou não.

Desculpa, talvez tenha me espressado mal anteriormente.
Aqui vai o exemplo de teste que estou fazendo para encontrar a solução:

public static void main(String[] args) { Session session1 = HibernateController.getSession(); // cria uma nova instância da Session. Session session2 = HibernateController.getSession(); PessoaJuridica pessoa1 = (PessoaJuridica) session1.load(PessoaJuridica.class, new Integer(3)); PessoaJuridica pessoa2 = (PessoaJuridica) session2.load(PessoaJuridica.class, new Integer(3)); try { System.out.println(pessoa2.getNome()); // imprime "João" pessoa1.setNome("José"); session1.flush(); session1.connection().commit(); session2.refresh(pessoa2); System.out.println(pessoa2.getNome()); // imprime "João" } catch (ApxException e) { e.printStackTrace(); } catch (HibernateException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } }
Esse simples exemplo, mostra o meu problema, tenho 2 objetos iguais carregados, à partir de sessões diferentes.
Necessito sincronizar eles. O refresh não funcionou.
Alguma idéia?

Tente assim:

Session session1 = HibernateController.getSession();
Session session2 = HibernateController.getSession();
PessoaJuridica pessoa1 = (PessoaJuridica) session1.load(PessoaJuridica.class, new Integer(3));
PessoaJuridica pessoa2 = (PessoaJuridica) session2.load(PessoaJuridica.class, new Integer(3));
System.out.println(pessoa2.getNome()); // imprime "João"
Transaction tx = session1.beginTransaction();
pessoa1.setNome("José");
tx.commit();
session1.close();
session2.refresh(pessoa2);
System.out.println(pessoa2.getNome()); // imprime "João"

Ainda nada, realmente não entendo, pois no console sai isso:

João
Hibernate: /* load br.com.ampix.adm.objetos.PessoaJuridica / …
Hibernate: /
update br.com.ampix.adm.objetos.PessoaJuridica / …
Hibernate: /
load br.com.ampix.adm.objetos.PessoaJuridica */ …
João

Ou seja, após o update da pessoa1, ele realmente faz um load da pessoa2, o que eu não entende, é porque não fica atualizado.

amigo,

vc conseguiu resolver o problema?

estou com a mesma situação aki…