Bom dia pessoal,
Alguém já tentou utilizar o MyFaces Orchestra em conjunto com o Spring para prover o scopo de conversação no JSF 2?
Será que é uma boa alternativa?
Problema: Gostaria de manter o EntityManager aberto durante a transição entre páginas relacionadas.
Por exemplo, tenho um formulário em que executo uma consulta, seleciono um dos resultados da consulta (aqui o método objEntityManager.find… é disparado) para carregar no formulário de edição, a view é renderizada e o entity manager é fechado (isto através do OpenEntityManagerInViewFilter e o objeto é “desconectado”. Então executo uma alteração neste objeto e executo uma action “save”, esta action do meu managed bean vai indiretamente executar o update no banco. Funciona, mas para isso eu tenho que fazer uma manobra para obter novamente o objeto “gerenciado” pelo entitymanager e atualizado com as alterações realizadas.
A arquitetura atual dos projetos está baseada nestes frameworks/tecnologias:
Persistência: JPA com Hibernate, Spring para Gerenciamento de Transação;
Injeção de Dependência: Spring;
Visão: JSF (Mojarra, Primefaces), em uma aplicação, REST (JBoss RESTEasy), em outra aplicação. (todas as aplicações são baseadas nos mesmos projetos base, praticamente implementando os controllers em cada aplicação).
O projeto é um tanto grande (na verdade mais de um projeto), então segue somente a parte da implementação relacionada diretamente com o problema:
Fragmentos do ManagedBean:
public boolean doEdit() {
this.objetoAtual = this.getSelectedValue();
//...algumas outras coisas instruções
return true;
}
protected T getSelectedValue() {
//...algumas outras coisas instruções
return (T) this.getSearchableService().findById(
(Integer) value);
}
protected boolean doSave() {
//...algumas outras coisas instruções
this.objetoAtual = this.service.update(this.objetoAtual);
//...algumas outras coisas instruções
return true;
}
Fragmentos da implementação do service:
public T findById(Integer id) {
return this.getDao().findById(id);
}
public T update(T entity) {
T managedEntity = null;
// aqui eu obtenho a entidade gerenciada, e copia os dados atualizados a partir do objeto entity
managedEntity = this.getManagedEntity(entity);
// aqui eu processo atualização das coleções (inclusões, exclusões e atualizações de objetos das listas relacionadas através de @OneToMany
this.processCollectionFields(managedEntity, entity);
// Retorna a entidade atualizada (persistida automaticamente final
// da transação
return managedEntity;
}
Fragmentos do objeto dao:
public class AbstractJpaDao<T extends AbstractEntity> implements Dao<T> {
private static final long serialVersionUID = -4183354590641889512L;
@PersistenceContext
protected EntityManager em;
protected EntityManagerFactory emf;
private Class<T> type;
public AbstractJpaDao() {
super();
}
//...outros métodos
@Override
public T findById(Integer id) {
return this.em.find(this.type, id);
}
//...outros métodos
Se não conseguir resolver com Spring, penso em migrar a arquitetura para JEE 6: JSF, JPA, CDI (Weld). A questão é que com a arquitetura atual eu consigo coisas como debugar minha aplicação no Jetty (Eclipse, Maven) em desenvolvimento e fazer deploy em qualquer container/application server: Tomcat, JBoss AS são os que tenho em mente para produção.
Obs.: O projeto ainda está em andamento.