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
[code]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();
}
}[/code]
e também implementar a classe ViewScopeCallbackRegister…
[code]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;
}
}[/code]
o problema é o seguinte, ai tenho um controller simples somente para buscar e adicionar um registro no banco …
[code]@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;
}[/code]
Reparem no @Scope(“view”) ele é detectado pois adicionei no faces os seguines listeners
[code]
main.java.test.scope.ViewScopeCallbackRegistrer
javax.faces.event.PostConstructViewMapEvent
javax.faces.component.UIViewRoot
<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>[/code]
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);
}
}
...
}[/code]
e meu UsuarioDaoImpl
[code]
@Component("usuarioDao")
public class UsuarioDaoImpl extends GenericDaoImpl<Usuario> implements UsuarioDao, Serializable {
private static final long serialVersionUID = -5854504549891863705L;
}
[/code]
Agora o applicationContext.xml com a declaração do Scope e a parte do transactionManager..
[code]<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.