Scope view, JSF2+Spring3+Hibernate não insere no banco

3 respostas
D
Bom pessoal, estou utilizando JSF2+Spring3+Hibernate.. estou a 2 semanas ja sem conseguir fazer esse view funcionar.. e peço ajuda Então, estou gerenciando os Scopes pelo spring(adicionei)..
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
no faces-config Pois então, estou precisando view scope, e não sei porque causa motivo razão ou circunstância o spring não traz este recurso, então tive que implementalo.. Segui um tutorial em ingles.. ficou da seguinte maneira.. Cria-se a classe ViewScope
package main.java.test.scope;

import java.util.Map;

import javax.faces.context.FacesContext;

import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;
import org.springframework.web.context.request.FacesRequestAttributes;

public class ViewScope implements Scope {

	public static final String VIEW_SCOPE_CALLBACKS = "viewScope.callbacks";

	public synchronized Object get(String name, ObjectFactory<?> objectFactory) {
		Object instance = getViewMap().get(name);
		if (instance == null) {
			instance = objectFactory.getObject();
			getViewMap().put(name, instance);
		}
		return instance;
	}

	public Object remove(String name) {
		Object instance = getViewMap().remove(name);
		if (instance != null) {
			Map<String, Runnable> callbacks = (Map<String, Runnable>) getViewMap().get(VIEW_SCOPE_CALLBACKS);
			if (callbacks != null) {
				callbacks.remove(name);
			}
		}
		return instance;
	}

	public void registerDestructionCallback(String name, Runnable runnable) {
		Map<String, Runnable> callbacks = (Map<String, Runnable>) getViewMap().get(VIEW_SCOPE_CALLBACKS);
		if (callbacks != null) {
			callbacks.put(name, runnable);
		}
	}

	public Object resolveContextualObject(String name) {
		FacesContext facesContext = FacesContext.getCurrentInstance();
		FacesRequestAttributes facesRequestAttributes = new FacesRequestAttributes(facesContext);
		return facesRequestAttributes.resolveReference(name);
	}

	public String getConversationId() {
		FacesContext facesContext = FacesContext.getCurrentInstance();
		FacesRequestAttributes facesRequestAttributes = new FacesRequestAttributes(facesContext);
		return facesRequestAttributes.getSessionId() + "-" + facesContext.getViewRoot().getViewId();
	}

	private Map<String, Object> getViewMap() {
		return FacesContext.getCurrentInstance().getViewRoot().getViewMap();
	}
}
e também implementar a classe ViewScopeCallbackRegister..
package main.java.test.scope;
import java.util.HashMap;
import java.util.Map;

import javax.faces.component.UIViewRoot;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.PostConstructViewMapEvent;
import javax.faces.event.PreDestroyViewMapEvent;
import javax.faces.event.SystemEvent;
import javax.faces.event.ViewMapListener;

public class ViewScopeCallbackRegistrer implements ViewMapListener {

	public void processEvent(SystemEvent event) throws AbortProcessingException {
		if (event instanceof PostConstructViewMapEvent) {
			PostConstructViewMapEvent viewMapEvent = (PostConstructViewMapEvent) event;
			UIViewRoot viewRoot = (UIViewRoot) viewMapEvent.getComponent();
			viewRoot.getViewMap().put(ViewScope.VIEW_SCOPE_CALLBACKS, new HashMap<String, Runnable>());
		} else if (event instanceof PreDestroyViewMapEvent) {
			PreDestroyViewMapEvent viewMapEvent = (PreDestroyViewMapEvent) event;
			UIViewRoot viewRoot = (UIViewRoot) viewMapEvent.getComponent();
			Map<String, Runnable> callbacks = (Map<String, Runnable>) viewRoot.getViewMap().get(ViewScope.VIEW_SCOPE_CALLBACKS);
			if (callbacks != null) {
				for (Runnable c : callbacks.values()) {
					c.run();
				}
				callbacks.clear();
			}
		}
	}

	public boolean isListenerForSource(Object source) {
		return source instanceof UIViewRoot;
	}
}
o problema é o seguinte, ai tenho um controller simples somente para buscar e adicionar um registro no banco ..
@Controller
@Scope("view")
public class UsuarioController implements Serializable {

	private static final long serialVersionUID = -3704274460284324174L;

	@Autowired
	private UsuarioDao usuarioDao;

	private Usuario usuario;

	@PostConstruct
	public void init() {
		setUsuario(new Usuario());
	}

	@Transactional(readOnly=false,propagation=Propagation.REQUIRED)
	public void salvar() {
		usuarioDao.findById(1l);
		usuarioDao.save(getUsuario());
		FacesMessage fm = new FacesMessage("Usuário criado com sucesso");
		fm.setSeverity(FacesMessage.SEVERITY_INFO);
		FacesContext.getCurrentInstance().addMessage(null, fm);
	}
	public Usuario getUsuario() {
		return usuario;
	}
Reparem no @Scope("view") ele é detectado pois adicionei no faces os seguines listeners
<system-event-listener>
			<system-event-listener-class>main.java.test.scope.ViewScopeCallbackRegistrer</system-event-listener-class>
			<system-event-class>javax.faces.event.PostConstructViewMapEvent</system-event-class>
			<source-class>javax.faces.component.UIViewRoot</source-class>
		</system-event-listener>

		<system-event-listener>
			<system-event-listener-class>main.java.test.scope.ViewScopeCallbackRegistrer</system-event-listener-class>
			<system-event-class>javax.faces.event.PreDestroyViewMapEvent</system-event-class>
			<source-class>javax.faces.component.UIViewRoot</source-class>
		</system-event-listener>
Bom, vou tentar resumir a parte Dao agora, Tenho um GenericDao (interface) e a GenericDaoImpl a Impl esta da seguinte maneira
@Repository
@Transactional(readOnly = true, propagation = Propagation.REQUIRED)
public class GenericDaoImpl<T> implements GenericDao<T> {

	private Class<T> entityClass;

	@PersistenceContext
	private EntityManager entityManager;

	@PersistenceContext
	public void setEntityManager(EntityManager entityManager) {
		this.entityManager = entityManager;
	}

	public EntityManager getEntityManager() {
		return entityManager;
	}

	@SuppressWarnings("unchecked")
	public void getEC() {
		this.entityClass =(Class<T>) ((ParameterizedType)  getClass().getGenericSuperclass()).getActualTypeArguments()[0];
	}

	@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
	public void save(GenericModel entity) {
		GenericModel genericModel = (GenericModel) entity;
		if (genericModel.getDataCadastrado() == null) {
			genericModel.setDataCadastrado(new Date());
		}
		if (genericModel.getCadastradoPor() == null) {
			genericModel.setCadastradoPor("suario");
		}
		genericModel.setAlteradoPor("suario");
		genericModel.setDataAlterado(new Date());
		if (genericModel.getId() == null || genericModel.getId() == 0) {
			this.getEntityManager().persist(genericModel);
		} else {
			this.getEntityManager().merge(genericModel);
		}
	}
...
}
e meu UsuarioDaoImpl
@Component("usuarioDao")
public class UsuarioDaoImpl extends GenericDaoImpl<Usuario> implements UsuarioDao, Serializable {

private static final long serialVersionUID = -5854504549891863705L;

}
Agora o applicationContext.xml com a declaração do Scope e a parte do transactionManager..
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
		<property name="scopes">
			<map>
				<entry key="view">
					<bean class="main.java.test.scope.ViewScope" />
				</entry>
			</map>
		</property>
	</bean>

	<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
		<property name="entityManagerFactory" ref="entityManagerFactory" />
	</bean>
	<tx:annotation-driven  proxy-target-class="true" transaction-manager="transactionManager" />
.. Agora a grande dúvida. quando utilizo o scope view ele não injeta meu persistenceContext.. começa o problema por ae.. Então eu passo o context diretamente para o UsuarioDaoImpl (sobrepondo o do GenericDaoImpl), ai ele injeta normalmente, e então ao acessar o meu controlador ele reconhece a view (cai nos metodos get do ViewScope, tudo certo pelo debug) Porem ele não insere NADA no banco, somente faz select, e o pior.. não apresenta erro algum, simplesmente passa no persist e não gera o sql de insercao no console, E se eu troco para request ou session e funciona perfeitamente, alguem ja passou por este problema, ou tem esta parte do view scope implementado em algum projeto de exemplo? Agradeço! Obrigado a todos.

3 Respostas

D

Ninguem então?

R

Olá Debiasi,

Conseguiu resolver o problema?
Estou com o mesmo problema, alguém pode ajudar?

Valeu

R

Consegui resolver.

Não sei ainda o porquê, mas o problema estava na implementação do JSF do MyFaces, pois troquei para o Mojarra e tudo funcionou normalmente.

Criado 9 de dezembro de 2011
Ultima resposta 5 de abr. de 2012
Respostas 3
Participantes 2