vRaptor + Hibernate - java.lang.IllegalArgumentException: attempt to create saveOrUpdate event

Bom dia Pessoal,
Estou com problema na parte basica do uso do hibernate com o vRaptor.
Quando temto adicionar os campos obtidos de um formulario, ele lança a Exception!!

Efetuei testes com console e o hibernate funfou legal, o problema é quando vai para o vRaptor…
Quem puder ajuda ai Galera…

Os arquivos utilizados estao abaixo:

A Exception

br.com.caelum.vraptor.InterceptionException: an exception was raised while executing resource method
	br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:86)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:77)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:42)
	br.com.caelum.vraptor.core.InstantiatedInterceptorHandler.execute(InstantiatedInterceptorHandler.java:47)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.interceptor.InterceptorListPriorToExecutionExtractor.intercept(InterceptorListPriorToExecutionExtractor.java:46)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:80)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:67)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.core.DefaultRequestExecution.execute(DefaultRequestExecution.java:70)
	br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
	br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:56)
	br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)
root cause

java.lang.IllegalArgumentException: attempt to create saveOrUpdate event with null entity
	org.hibernate.event.SaveOrUpdateEvent.<init>(SaveOrUpdateEvent.java:63)
	org.hibernate.event.SaveOrUpdateEvent.<init>(SaveOrUpdateEvent.java:46)
	org.hibernate.impl.SessionImpl.save(SessionImpl.java:551)
	org.hibernate.impl.SessionImpl.save(SessionImpl.java:547)
	br.com.probank.sigos.dao.TermoAceiteDao.salva(TermoAceiteDao.java:28)
	br.com.probank.sigos.controller.TermoAceiteController.adicionaTermoAceite(TermoAceiteController.java:25)
	sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	java.lang.reflect.Method.invoke(Unknown Source)
	br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:57)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:77)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:42)
	br.com.caelum.vraptor.core.InstantiatedInterceptorHandler.execute(InstantiatedInterceptorHandler.java:47)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.interceptor.InterceptorListPriorToExecutionExtractor.intercept(InterceptorListPriorToExecutionExtractor.java:46)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:80)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:67)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.core.DefaultRequestExecution.execute(DefaultRequestExecution.java:70)
	br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
	br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:56)
	br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)
note The full stack trace of the root cause is available in the Apache Tomcat/6.0.20 logs.

Hibernate Config

hibernate.dialect org.hibernate.dialect.MySQLDialect
hibernate.connection.driver_class com.mysql.jdbc.Driver
hibernate.connection.url jdbc:mysql://localhost/fj21
hibernate.connection.username root
hibernate.connection.password root

HibernateUtil

package br.com.probank.sigos.hibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

import br.com.probank.sigos.bean.TermoAceite;

public class HibernateUtil {

	private static SessionFactory factory;

	static {

		AnnotationConfiguration cfg = new AnnotationConfiguration();
		cfg.addAnnotatedClass(TermoAceite.class);
		factory = cfg.buildSessionFactory();

	}

	public Session getSession() {
		System.out.println("COnexao estabelecida");
		return factory.openSession();
	}

}

O Bean

package br.com.probank.sigos.bean;

import java.util.Calendar;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;


@Entity
@Table(name="gos07_ta")
public class TermoAceite {
	@Id
	private double num_ta;
	private String num_demanda_02;
	private String demanda_02;
	private String num_os_02;
	private Calendar dt_ta;
	private String sistema;
	private double vlr_ta;
	
	public double getNum_ta() {
		return num_ta;
	}
	public String getNum_demanda_02() {
		return num_demanda_02;
	}
	public void setNum_ta(double numTa) {
		num_ta = numTa;
	}
	public void setNum_demanda_02(String numDemanda_02) {
		num_demanda_02 = numDemanda_02;
	}
	public void setDemanda_02(String demanda_02) {
		this.demanda_02 = demanda_02;
	}
	public void setNum_os_02(String numOs_02) {
		num_os_02 = numOs_02;
	}
	public void setDt_ta(Calendar dtTa) {
		dt_ta = dtTa;
	}
	public void setSistema(String sistema) {
		this.sistema = sistema;
	}
	public void setVlr_ta(double vlrTa) {
		vlr_ta = vlrTa;
	}
	public String getDemanda_02() {
		return demanda_02;
	}
	public String getNum_os_02() {
		return num_os_02;
	}
	public Calendar getDt_ta() {
		return dt_ta;
	}
	public String getSistema() {
		return sistema;
	}
	public double getVlr_ta() {
		return vlr_ta;
	}	
	
	
	
	
}

O Dao dele

package br.com.probank.sigos.dao;

import java.util.List;




import org.hibernate.Session;
import org.hibernate.Transaction;

import br.com.caelum.vraptor.ioc.Component;
import br.com.caelum.vraptor.ioc.RequestScoped;
import br.com.probank.sigos.bean.TermoAceite;
import br.com.probank.sigos.hibernate.HibernateUtil;

@Component
@RequestScoped
public class TermoAceiteDao {

	private final Session session;

	public TermoAceiteDao() {
		this.session = new HibernateUtil().getSession();
	}

	public void salva(TermoAceite ta) {
		Transaction tx = session.beginTransaction();
		session.save(ta);
		tx.commit();
	}

	public List<TermoAceite> lista() {
		return session.createCriteria(TermoAceite.class).list();
	}

}

Controller

package br.com.probank.sigos.controller;

import br.com.caelum.vraptor.Resource;
import br.com.probank.sigos.bean.TermoAceite;
import br.com.probank.sigos.dao.TermoAceiteDao;

@Resource
public class TermoAceiteController {

	private TermoAceiteDao tadao;
	
	public TermoAceiteController(TermoAceiteDao tadao){
		this.tadao = tadao;
	}
	
	public void consultaTermosAceite(){
		tadao.lista();		
	}
	
	public void formularioTermoAceite(){
		
	}
	
	public void adicionaTermoAceite(TermoAceite ta){
		tadao.salva(ta);
	}
	
	
}

O Formulario

[code]]
<%@ taglib uri=“http://java.sun.com/jsp/jstl/core” prefix=“c” %>

Inserindo Termo de Aceite
<form action="<c:url value="/termoAceite/adicionaTermoAceite"/>">
<table>
	<tr>
		<th>Numero</th>
		<td><input type="text" name="termoaceite.num_ta" /></td>
	</tr>
	<tr>
		<th>Numero da Demanda</th>
		<td><input type="text" name="termoAceite.num_demanda_02" /></td>
	</tr>
	<tr>
		<th>Demanda</th>
		<td><input type="text" name="termoAceite.num_demanda_02" /></td>
	</tr>
	<tr>
		<th>Ordem de Servico</th>
		<td><input type="text" name="termoAceite.num_os_02" /></td>
	</tr>
	<tr>
		<th>Data</th>
		<td><input type="text" name="termoAceite.dt_ta" /></td>
	</tr>
	<tr>	
		<th>Sistema</th>
		<td><input type="text" name="termoAceite.sistema" /></td>
	</tr>
	<tr>	
		<th>Valor TA</th>
		<td><input type="text" name="termoAceite.vlr_ta" /></td>
	</tr>
	<tr colspan="2">
		<td><input type="submit" value="Inserir"/></td>
	</tr>
</table>	
</form>
[/code]

Valeu pessoal!!

Esse erro indica que você está tentando salvar um objeto nulo. Mas por que está nulo?

Note que no seu JSP você usa o nome dos campos como termoaceite.*, mas no seu controller você recebe como ta. O correto é que o nome do campo no JSP seja o caminho para chegar na propriedade, ou seja, você deve alterar para isso seu método no controller:

Além disso não use esse HibernateUtil nem mesmo controle manualmente a transação. Isso é bem feio :D, e além disso o Vraptor já faz esse trabalho para você. Há muitos posts meus explicando isso para o pessoal, de uma olhada nas minhas mensagens enviadas.

Há também uma documentação no site do Vraptor: http://vraptor.caelum.com.br/documentacao/componentes-utilitarios-opcionais/

Basicamente você precisa adicionar as linhas abaixo no seu web.xml, apagar sua HibernateUtil, apagar as linhas que possuem transaction.commit, transaction.rollback e afins.

<context-param> <param-name>br.com.caelum.vraptor.provider</param-name> <param-value>br.com.caelum.vraptor.util.hibernate.HibernateCustomProvider</param-value> </context-param>

Muito obrigado Garcia, funcionou direitinho.

Achei muito trabalhoso abrir transação e dar commit em todas operações, vou ler o conteudo para minimizar código…
Sobre o HibernateUtil, pensei que fosse um padrão. Vou dar uma lida sobre tambem.

Abraço

Em projetos onde você trabalha com um ambiente gerenciado (vide EJB) você não precisa disso, pois o entity-manager é injetado automagicamente para você. Frameworks como o Spring também fazem esse trabalho todo para você, e o Vraptor também possui essa funcionalidade.

Essa classe HibernateUtil é bem útil quando você está em algum projeto que você não use nenhuma das opções que citei acima. No seu caso como o Vraptor já faz isso ela é desnecessária. A vantagem também é escrever menos código.

[quote=garcia-jj]
Em projetos onde você trabalha com um ambiente gerenciado (vide EJB) você não precisa disso, pois o entity-manager é injetado automagicamente para você. Frameworks como o Spring também fazem esse trabalho todo para você, e o Vraptor também possui essa funcionalidade.

Essa classe HibernateUtil é bem útil quando você está em algum projeto que você não use nenhuma das opções que citei acima. No seu caso como o Vraptor já faz isso ela é desnecessária. A vantagem também é escrever menos código.[/quote]

Mas como controlamos a sessão utilizando este recurso? Fui na documentação do vRaptor, e encontrei justamente o que me disse, mas daí fico perdido quanto a sessao. Obrigado.

o vraptor abre a sessao (e uma transação) no começo da requisição, e fecha (e commita ou dá rollback na transação) no fim da requisição… uma impl do open session in view

Então deixamos essa parte para o vRaptor tomar conta, mas e no método salva, como irei pegar a sessao para executar o save (session.save()), ja que nao tenho mais ela?

vc recebe a session no construtor da classe… o vraptor injeta essa sessão pra vc, já aberta e dentro de uma transação