[RESOLVIDO] Spring+Hibernate não atualiza objeto, sempre cria um novo quando altero algum dado

5 respostas
R
Bom dia pessoal, sou novato e estou tentando implementar uma aplicação utilizando Spring, Hibernate e Primefaces, mas estou com um problema para atualizar meus objetos, não importa a forma que eu faça ele não salva as alterações, ele sempre cria um novo objeto. O que posso estar fazendo de errado, já tentei utilizar o update e também o comando merge e nenhum resolveu. Segue context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context reloadable="true">
	<Resource name="jdbc/protocolo"
	auth="Container"
	type="javax.sql.DataSource"
	maxActive="100"
	maxIdle="5"
	maxWait="1800"
	username="teste"
	password="teste"
	driverClassName="org.postgresql.Driver"
	url="jdbc:postgresql://101.186.39.254:5432/protocolo?autoReconnect=true"/>
Segue web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	id="WebApp_ID" version="3.0">	
	<display-name>Protocolo</display-name>
	<context-param>
   		<param-name>javax.faces.CONFIG_FILES</param-name>
    	<param-value>/WEB-INF/faces-config.xml</param-value>
 	</context-param>
 	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			/WEB-INF/applicationContext.xml
			/WEB-INF/applicationContext-security.xml
		</param-value>
	</context-param>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<listener>
   		<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
  	</listener> 	
	<servlet>
		<servlet-name>Faces Servlet</servlet-name>
		<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
    	<servlet-name>Faces Servlet</servlet-name>
    	<url-pattern>*.jsf</url-pattern>
  	</servlet-mapping>
  	<servlet-mapping>
    	<servlet-name>Faces Servlet</servlet-name>
    	<url-pattern>*.xhtml</url-pattern>
  	</servlet-mapping>
  	<servlet-mapping>
  	    <servlet-name>Faces Servlet</servlet-name>
    	<url-pattern>/faces/*</url-pattern>
 	</servlet-mapping>
	<session-config>
        <session-timeout>
           -1
        </session-timeout>
    </session-config>
    <error-page>
    	<exception-type>
       		 javax.servlet.ServletException
    	</exception-type>
   		<location> 
        	/publico/login.xhtml 
    	</location>
	</error-page>
	<context-param>
    	<param-name>javax.faces.PROJECT_STAGE</param-name>
    	<param-value>Development</param-value>
  	</context-param>	
 	<welcome-file-list>
		<welcome-file>publico/login.xhtml</welcome-file>
	</welcome-file-list>
	<context-param>
		<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
		<param-value>client</param-value>
	</context-param>
	<context-param>
		<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
		<param-value>resources.application</param-value>
	</context-param>
	<listener>
    	<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
  	</listener> 	
	<resource-ref>
		<description>DataSource protocolo</description>
		<res-ref-name>jdbc/protocolo</res-ref-name>
		<res-type>javax.sql.DataSource</res-type>
		<res-auth>Container</res-auth>
	</resource-ref>
	<resource-ref>
		<description>Mail Session</description>
		<res-ref-name>mail/Session</res-ref-name>
		<res-type>javax.mail.Session</res-type>
		<res-auth>Container</res-auth>
	</resource-ref>	
	<filter>
		<filter-name>springSecurityFilterChain</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>springSecurityFilterChain</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>	
	<context-param>
		<param-name>primefaces.THEME</param-name>
		<param-value>hot-sneaks</param-value>
	</context-param>
</web-app>

AplicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
					  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
				      http://www.springframework.org/schema/tx
					  http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
					  http://www.springframework.org/schema/context
					  http://www.springframework.org/schema/context/spring-context-3.0.xsd">
	
	<bean id="protocoloDS" class="org.springframework.jndi.JndiObjectFactoryBean">
		<property name="jndiName">
			<value>java:comp/env/jdbc/protocolo</value>
		</property>
	</bean>
	
	<context:component-scan base-package="br.com.pn" />
	<context:annotation-config />

	<bean id="SessionFactory"
		class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
		<property name="dataSource" ref="protocoloDS" />	
		<property name="annotatedClasses">
		<list>
			<value>br.com.pn.dominio.Protocolo</value>
			<value>br.com.pn.dominio.Usuario</value>
		</list>
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
				<prop key="hibernate.show_sql">false</prop>
				<prop key="hibernate.hbm2ddl.auto">update</prop>
			</props>
		</property>
	</bean>

	<tx:annotation-driven transaction-manager="txManager" />
	
	<bean id="txManager"
		class="org.springframework.orm.hibernate4.HibernateTransactionManager">
		<property name="sessionFactory" ref="SessionFactory" />
	</bean>
</beans>
Faces-config.xml
<?xml version="1.0"?>
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">

	<application>
		<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
	</application>
</faces-config>

Segue meu Bean, utilizo o mesmo salvar da inclusão, mas já tentei utilizar outro metodo, enviando para um update e tambem para um merge e não resolveu.

package br.com.pn.apresentacao;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.application.FacesMessage.Severity;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;

import org.primefaces.event.SelectEvent;
import org.primefaces.event.UnselectEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import br.com.pn.apresentacao.ProtocoloDataModule;
import br.com.pn.dominio.Protocolo;
import br.com.pn.servicos.ICadProtocolo;
import br.com.pn.servicos.IUsuarioService;

@Component
@Scope("request")
public class CadProtocoloBean {

	@Autowired
	private ICadProtocolo protocoloService;
	@Autowired
	private IUsuarioService usuarioService;
	
	private Protocolo protocolo = new Protocolo();

	private ProtocoloDataModule dmProtocolo;
	private List<Protocolo> protocolos = new ArrayList<Protocolo>();
	private List<Protocolo> protocolosFiltrados = new ArrayList<Protocolo>();

	// private StreamedContent arquivoRetorno;
	private int tipoRelatorio;
	private Long numProt;
	private String msg, msgDetalhe;
	private Severity tipoMsg = FacesMessage.SEVERITY_INFO;

	public void salvar() {		
		try {
			FacesContext context = FacesContext.getCurrentInstance();
			ExternalContext external = context.getExternalContext();
			if (protocolo.getDataPedido() == null)
				protocolo.setDataPedido(new Date());
			if (protocolo.getJustificativa() == null)
				protocolo.setDataResposta(new Date());
			if(protocolo.getCodigo().intValue()>0)
				protocoloService.update(protocolo);
			else
				protocoloService.salvar(protocolo);				
			protocolos.add(protocolo);
			if (!protocolosFiltrados.isEmpty())
				if (protocolosFiltrados.contains(protocolo) == false)
					protocolosFiltrados.add(protocolo);
			MensagemBean.mensagem(FacesMessage.SEVERITY_INFO,
					"Protocolo incluído com sucesso",
					" Para nova inclusão clique em limpar");

		} catch (Exception e) {
			MensagemBean.mensagem(FacesMessage.SEVERITY_ERROR,
					"Falhou a inclusão do protocolo", e.getMessage());
		}
	}	

	public void editar(Long numProt) {
		System.out.println(numProt);
		this.protocolo = protocoloService
				.buscarProtocolo(numProt);
	}
	
	

}

Minha Classe serviço.

package br.com.pn.servicos;

import java.util.List;

import org.springframework.transaction.annotation.Transactional;

import br.com.pn.dominio.Protocolo;
import br.com.pn.persistencia.ProtocoloDAO;

public interface ICadProtocolo {

	public abstract ProtocoloDAO getProtocoloDAO();

	public abstract void setProtocoloDAO(
			ProtocoloDAO protocoloDao);

	@Transactional
	public abstract void salvar(Protocolo protocolo);

	@Transactional
	public abstract void delete(Protocolo protocolo);

	@Transactional(readOnly = true)
	public abstract List<Protocolo> listarProtocolos();

	@Transactional(readOnly = true)
	public abstract Protocolo buscarProtocolo(
			Long codProtocolo);
	@Transactional
	public abstract void update(Protocolo protocolo);

}

e por fim a classe DAO

package br.com.pn.persistencia;

import java.util.List;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import br.com.pn.dominio.Protocolo;

@Repository("protocoloDao")
public class ProtocoloDAOImpl implements ProtocoloDAO {

	@Autowired
	private SessionFactory sessionFactory;

	/* (non-Javadoc)
	 * @see br.com.pn.persistencia.ProtocoloDAO#getSessionFactory()
	 */
	@Override
	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	/* (non-Javadoc)
	 * @see br.com.pn.persistencia.ProtocoloDAO#setSessionFactory(org.hibernate.SessionFactory)
	 */
	@Override
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	/* (non-Javadoc)
	 * @see br.com.pn.persistencia.ProtocoloDAO#get(int)
	 */
	@Override
	public Protocolo get(Long id) {
		Protocolo ptn = new Protocolo();
		ptn = (Protocolo) sessionFactory.getCurrentSession().load(
				Protocolo.class, id);
		System.out.println(ptn.getNomeBeneficiario());
		return ptn;
	}

	/* (non-Javadoc)
	 * @see br.com.pn.persistencia.ProtocoloDAO#getAll()
	 */
	@Override
	@SuppressWarnings("unchecked")
	public List<Protocolo> getAll() {
		return sessionFactory.getCurrentSession()
				.createQuery("from Protocolo").list();
	}

	/* (non-Javadoc)
	 * @see br.com.pn.persistencia.ProtocoloDAO#save(br.com.pn.dominio.Protocolo)
	 */
	@Override
	public void save(Protocolo prot) {
		System.out.println("save");
		sessionFactory.getCurrentSession().save(prot);
	}
	
	/* (non-Javadoc)
	 * @see br.com.pn.persistencia.ProtocoloDAO#save(br.com.pn.dominio.Protocolo)
	 */
	@Override
	public void update(Protocolo prot) {
		sessionFactory.getCurrentSession().merge(prot);
	}

	/* (non-Javadoc)
	 * @see br.com.pn.persistencia.ProtocoloDAO#delete(br.com.pn.dominio.Protocolo)
	 */
	@Override
	public void delete(Protocolo prot) {
		sessionFactory.getCurrentSession().delete(prot);
	}	

}

5 Respostas

D

vc já verificou se o objeto Protocolo que vc esta mandando altera tem um id setado , se não tiver o hibernate vai criar um novo mesmo vc usando o marge

debug a aplicação e verifique isso

R

Danilo é isso mesmo, não tem id e mesmo no objeto que eu busco no banco no metodo editar vem sem o id, porque será?

public void editar(Long numProt) {
		System.out.println(numProt); // imprime o codigo do protocolo do table
		this.protoco = protocoloService
				.buscarProtocolo(numProt);
		System.out.println(this.protocolo.getCodigo()); // imprime null
	}
D

posta o código da entidade

R

Resolvido, era porque no meu xhtml, o input do primefaces para o código estava enable=false, alterei para true e funcionou, agora vou procurar uma forma de barra a alteração deste código. Obrigado.

D

quando for edição coloca essa valor como um outputText

e coloca um h:inputHidden com o valor do id

assim vc vai exibir o código do protocolo, mas o usuário não vai poder altera-lo e com o inputHidden quando vc submeter o formulário o código do protocolo será enviado tambem

Criado 6 de maio de 2013
Ultima resposta 6 de mai. de 2013
Respostas 5
Participantes 2