Mapeamentos no hibernate - URGENTE!

Pessoal, estou tendo um pequeno problema com mapeamentos entre duas classes Contato e DetalhesContato. Existe entre essas duas classes uma relação de 1:N respectivamente, isto é, para cada contato eu posso ter N detalhes de contato. O que gostaria que acontecesse é que: Quando um contato for adicionado na tabela de contatos automaticamente os detalhes do mesmo sejam adicionados na tablela de detalhes do contato. E da mesma forma aconteça para atualizações, (caso um contato seja atualizado, ele passe por todos os detalhes e atualize se necessario).
Só que estou encontrando problemas em entender como devo fazer os mapeamentos. Vou colocar abaixo as duas classes e os dois arquivos de mapeamento.
Agradeço a ajuda.

public final class Contato {
	private int codigo;
	private String nome;
	private Set detalhes;

	< getters e setters >
}
public final class DetalheContato {
	private int numero; // apenas um identificador
	private String detalhe;
	private int codContato; // campo que informa qual é o contato deste detalhe. É uma chave estrengeira para o contato.

	< getters e setters >
}

Contato.hbm.xml:

<hibernate-mapping package="model">
<class name="model.Contato" table="CONTATOS">
     <id name="codigo" column="CODIGO" type="int">
        <generator class="increment"/>
     </id>

     <property name="nome" column="NOME" type="java.lang.String" length="50" not-null="false"/>

     <set name="detalhes">
         <key column="COD_CONTATO"/>
         <one-to-many class="model.DetalheContato"/>
     </set>
</class>
</hibernate-mapping>

DetalheContato.hbm.xml:

<hibernate-mapping package="model"> 
<class name="model.DetalheContato" table="DETALHES_CONTATO">
     <id name="numero" column="NUMERO" type="int">
        <generator class="increment"/>
     </id>

     <property name="detalhe" column="DETALHE" type="java.lang.String" length="60" not-null="false"/> 

     <many-to-one name="codContato" class="model.Contato" column="COD_CONTATO"/>
</class> 
</hibernate-mapping> 

Codigo da classe dos testes:

   ...

   Contato contato = new Contato();
   contato.setNome("Nome Completo do Contato");
   contato.setEmail("srContato@concresul.com");

   DetalheContato detalhe = new DetalheContato();
   detalhe.setDescricao("fone res: (54) 456-8978");

   Set detalhes = new HashSet();
   detalhes.add(detalhe);

   contato.setDetalhes(detalhes);
   
   ... < gravação do contato usando classe de persistencia >

Seguem também, pra facilitar, as tabelas de CONTATOS e DETALHES_CONTATO (estou usando firebird):

CREATE TABLE CONTATOS 
(
  CODIGO INTEGER NOT NULL,
  NOME	 VARCHAR(50),
  CONSTRAINT PK_CONTATOS PRIMARY KEY (CODIGO)
);

CREATE TABLE DETALHES_CONTATO 
(
  NUMERO	 SMALLINT NOT NULL,
  COD_CONTATO	 INTEGER,
  DETALHE	 VARCHAR(60),
  CONSTRAINT PK_DETALHES_CONTATO PRIMARY KEY (NUMERO)
);

Acredito que tenha algum erro nos mapeamentos. Atualmente a mensagem de erro que retorna é:
Hibernate: insert into CONTATOS (NOME, CODIGO) values (?, ?)
Hibernate: update DETALHES_CONTATO set COD_CONTATO=? where NUMERO=?

Observem q ele tenta atualizar a segunda tabela e inserir na primeira (é meio estranho neh? :slight_smile: ) (tentei colocar algumas propriedades no mapeamento DetalheContato.hbm.xml do tipo cascate=“all” (tentei outros tb), insert=“true” update=“false”, … mas nada adiantou…

Outra coisa que observei é o seguinte: Uso na classe DetalheContato um campo int codContato, não sei se este não deveria ao inves de ser um int, ser um objeto Contato. (apesar de jah ter feito testes usando um obj e obtenho o mesmo erro!)

Observem que na tabela de detalhes não disse que COD_CONTATO é uma chave estrangeira para tabela de contatos, porque acredito não ser necessario, já que são feitos mapeamentos disso no hibernate…

Galera mais uma vez muito obrigado…

[b][size=“12”]
[color=“red”]

  • Editado: Aumente as chances de alguém responder o seu tópico. Use BBCode em seus códigos para mantê-los identados e mais legíveis para outros usuários. - Matheus[/color][/size][/b] :joia:

Caio,

essa não é uma mensagem de erro, é apenas informativa…

O Hibernate está gerando uma Exception na sua aplicação, ou não?

Que problemas vc está encontrando? Qual o efeito q vc espera no BD? O q acontece realmente?

Abraço.

André.

oi,

vc deve colocar

Olá,
Na verdade eu deixei de postar a msg de erro que ele mostra… Ele lança a exceção:

ERROR SessionImpl:2269 - Could not synchronize database state with session
net.sf.hibernate.HibernateException: SQL update or deletion failed (row not found)

A respeito do inverse=“true”, estou usando agora, mas mesmo assim não resolveu…
Neste forum (em ingles) vi que o pesssoal passou pelo mesmo problema…
http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=78&t=000083

Cara, esse erro ocorre porque o objeto que vc esta tentando gravar possui um numero de versão diferente com o que vc quer atualizar!
Esse problema é se sincronismo, pensa comigo, vc esta no ambiente web onde o numero de clientes é infinito, eu pego e abro um registro para edição, ai voce pega e abre tb, ai vc salva antes de min, logo seguida eu vo e salvo, ocorre um problema de sincronismo!
O Hibernate resolve este problema atravéz do campo VERSAO! Quando vc recupera um objeto ele pega um numero para versão e só permite que o registro que possui este mesmo numero seja gravado!
Este campo esta faltando na sua tabela!
Mas esse erro ocorre tb quando vc tenta gravar uma chave que ja existe na tabela, o mesmo id para 2 objetos!
E no seu caso parece que ele esta tentando atualizar um registro ao invéz de inseri-lo!
Olhe lá, ele ta falando ROW not found!

Olá,
Obrigado por responder!
mas acredito q o problema nao venha a ser com version…
vi num exemplo no guj de prof. e turmas… eles n. usam esse tipo de controle… (acho q eh importante ter esse controle, mas acredito q não venha a ser essa a razao do problema)…

Só pra garantir…

q vc acha de fazer um teste com dois clients acessando sua aplicação no mesmo registro?