Hibernate, mapeamento 1:N com problema

Ae galera…
Tou precisando do help de vocês ai…

Eu tenho um mapeamento no Hibernate de um relacionamento 1:N. Até ai blz.
O problema é que quando eu faço um select, ele roda normal, mas na hora do insert, ele tá dando um erro como se não estivesse captando a id.
Não sei se fui claro, deixa eu imprimir o stack trace aqui para vocês verem.

[quote]org.hibernate.HibernateException: org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
at br.com.rastreautos.dao.DaoAbstrato.tratarExcecao(DaoAbstrato.java:77)
at br.com.rastreautos.dao.DaoAbstrato.saveOrUpdate(DaoAbstrato.java:27)
at br.com.rastreautos.dao.PerfilDAO.create(PerfilDAO.java:12)
at br.com.rastreautos.servlets.PerfilControle.doGet(PerfilControle.java:59)
at br.com.rastreautos.servlets.PerfilControle.doPost(PerfilControle.java:81)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:210)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:151)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:870)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:685)
at java.lang.Thread.run(Thread.java:619)
Caused by: org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:249)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:139)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at br.com.rastreautos.dao.DaoAbstrato.saveOrUpdate(DaoAbstrato.java:25)
… 19 more
Caused by: java.sql.BatchUpdateException: Field ‘PERCODIGO’ doesn’t have a default value
at com.mysql.jdbc.ServerPreparedStatement.executeBatch(ServerPreparedStatement.java:665)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:242)
… 27 more[/quote]

Alguém sabe ai o que pode ter ocorrido?
Sei que o problema é que o campo PERCODIGO não está sendo visto no insert. Alguém pode me dar uma ajuda… qualquer coisa será muitíssimo bem vindo.

Você pode postar o código da classe Perfil e da tabela perfil?
Dica: habilite o log do SQL no properties do Hibernate.

#log4j.properties

### log just the SQL

log4j.logger.org.hibernate.SQL=debug

Sem problemas…

–> Perfil.hbm.xml

–> Perfil.java

Se necessário postarei o da classe Porta também…
Vlw pelo help

Uma sugestão: troque o tipo long primitivo pela classe correspondente, coloque no construtor todos os atributos e serialize a classe.

public class Perfil  implements java.io.Serializable {

 private Long codigo; 
 private String nome;
 private Set<Porta> portas;

 public Perfil() {

 }
 
 public Perfil(Long codigo, String nome) {
  this.nome = nome;
  this.codigo = codigo;
 }

... getters and setters

} 

[quote=ze_kiefa]Uma sugestão: troque o tipo long primitivo pela classe correspondente, coloque no construtor todos os atributos e serialize a classe.
[/quote]

Blz, farei isso… mas só de antemão… pode me explicar pq serializar? Não estou muito a par do que a classe serialize faz

Vlw pelo help… vou testar!

---- editando

O código SQL gerado pelo Hibernate… veja que falta o campo PERCODIGO na inserção…

Ou rpaz… continua dando o mesmo problema!

Aceito qualquer sugestão… obg!

Vamos lá de novo!

Serializar uma classe significa guardar o estado dela.

Grosseiramente falando, quando a classe é instanciada com certos valores, a serialização permite guardar este recém-objeto em um meio físico (um arquivo por exemplo). Dessa maneira você não perde as informações dele e dispensa criar um outro objeto igual a este (fui claro?).
Através da serialização é que a persistência ocorre (Hibernate, Java 5, EJB 3 e por aí vai).

Lendo mais atentamente o erro do stack, percebi que o erro ocorre durante a inserção das portas (um Perfil possui várias Portas), como você tinha comentado anteriormente.

Segue uma sugestão da configuração da classe Porta.

faça a tentativa.

Caro ze_kiefa…

muito boa suas dicas… creio que entendi o serialize. Muito legal…

Segui suas dicas… antes de vc me responder já havia colocado o no mapeamento para Porta. Então coloquei inverse=true no map para Perfil.

Fiz conforme vc me falou, porém agora ele só insere o perfil… não insere mais as portas, aliás… nem tenta inserir pelo sql gerado pelo próprio hibernate.

Atuais
Perfil.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="br.com.rastreautos.sis">
  <class name="Perfil" table="perfis">
  	<id 
  		column="PERCODIGO"
  		name="codigo">
  		<generator class="increment" />
  	</id>
  	
  	<property name="nome" column="PERNOME" />
  	
  	<set name="portas" inverse="true" lazy="false">
		<key column="PERCODIGO" />
		<one-to-many class="Porta" />
	</set>
  	
  </class>
</hibernate-mapping>

Porta.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="br.com.rastreautos.sis">
  <class name="Porta" table="portas">
  	<id 
  		column="PORCODIGO"
  		name="codigo">
  		<generator class="increment" />
  	</id>
  	
        <!-- demais campos omitidos -->

  	<many-to-one name="perfil" class="Perfil" column="PERCODIGO" fetch="select" />
  	
  </class>
</hibernate-mapping>

Desde já agradeço o apoio até agora… por favor não pare.
Hehehe…

Um apequena alteração.

Repare nos dois novos atributos: insert e update na tag set.

Ou rapaz, voltamos ao mesmo erro de anteriormente…

mas agora informando que a coluna PERCODIGO não pode ser nula… quando o campo PERCODIGO deveria ser inserido automaticamente pelo Hibernate… listagem do servlet que executa o cadastro…

PerfilDAO p = new PerfilDAO();
Perfil perfil = new Perfil((String) request.getParameter("nomePerfil"));
Set<Porta> portas = new HashSet<Porta>();

Porta porta1 = new Porta();

portas.add(porta1);
perfil.setPortas(portas);
				
p.create(perfil);

Eu pensei que o Hibernate já pega-se automaticamente a id da classe perfil e fosse incluindo no campo percodigo da tabela pota.

O que você axa agora?

------------- editando

Só 1 detalhe… o insert e update não funavam… davam um erro no mapeamento, então substitui por [ cascade=“save-update” ]

Alterei o atributo lazy=true na classe Porta, logo toda Porta recuperará o seu Perfil.

 <?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 <hibernate-mapping package="br.com.rastreautos.sis">
   <class name="Perfil" table="perfis">
    <id
      column="PERCODIGO"
      name="codigo">
     <generator class="increment" />
    </id>
  
   <property name="nome" column="PERNOME" />
   <set name="portas" inverse="true" lazy="false">
     <key column="PERCODIGO" />
     <one-to-many class="Porta" />
   </set>
  </class>
</hibernate-mapping>
 
<?xml version="1.0"?>
 <!DOCTYPE hibernate-mapping PUBLIC
 	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 <hibernate-mapping package="br.com.rastreautos.sis">
   <class name="Porta" table="portas">
   	<id 
   		column="PORCODIGO"
   		name="codigo">
   		<generator class="increment" />
   	</id>
   	
         <!-- demais campos omitidos -->
 
   	 <many-to-one name="perfil" 
        	   class="Perfil"
                   cascade="save-update" 
                   lazy="true"
                  column="PERCODIGO"/>
   </class>
 </hibernate-mapping>

Resumo

  1. a classe Perfil tem lazy=false, isto é, as suas Portas não serão recuperadas;
  2. a classe Porta tem lazy=true, isto é, o seu Perfil será recuperado;
  3. Perfil tem inverse=true, ou seja, é reponsabilidade da Porta de salvar/atualizar o seu Perfil.

Acho que é isso.

Vamos tentar de novo!

Referência
Inside explanation of inverse=true
Mapeando Associações com Hibernate - Parte 1

Ou rapaz… está dando um erro no lazy=true do map Porta

Entende…

Kra, vlw mesmo por está me ajudando ai esse tempo.
Creio que seria mais rápido por msn ou skype…

meu skype: paulojribp
meu msn: paulo_jr17@hotmail.com

Se poder me add em qualquer um.
Grato desde já…

No Hibernate 3 lazy é por default true. Tira esse atributo daí!

Não te achei no Skype. Não uso MSN.
Procure-me por ze_kiefa (estou invísivel!)

T+!

[quote=ze_kiefa]No Hibernate 3 lazy é por default true. Tira esse atributo daí!

Não te achei no Skype. Não uso MSN.
Procure-me por ze_kiefa (estou invísivel!)

T+![/quote]

Ok, te adicionei no skype… so falta vc me aceitar eu creio.

Tirei o lazy e nada ainda. Ei rpz, eu ja tou ficando louco aqui

Vamo ver o q pdemos fazer pelo skype… vlw!