Mapeamento Hibernate

Pessoal, dps de 1 pesquisada fiz os seguintes mapeamentos:

cliente.hbm.xml - nao alterou nada

[code]<?xml version="1.0" encoding="UTF-8"?>

<class name="loja.Cliente" table="cliente">

	<id name="id" type="integer" column="id">
                    <generator class="increment"/>
	</id>

	<property name="nome" type="string" column="nome"/>
            <property name="endereco" type="string" column="endereco"/>
            <property name="bairro" type="string" column="bairro"/>
            <property name="numero" type="integer" column="numero"/>
            <property name="cidade" type="string" column="cidade"/>
            <property name="estado" type="string" column="estado"/>
            <property name="cep" type="string" column="cep"/>
            <property name="forma_pagamento" type="string" column="forma_pagamento"/>
            <property name="info_pagamento" type="string" column="info_pagamento"/>
            <property name="data" type="date" column="data"/>
	
	<set name="produtos"
		 table="pedido">

		<key column="fk_cliente"/>
		<many-to-many class="loja.Produto" column="fk_produto"/>

	</set>

</class>

[/code]

produto.hbm.xml - tb nao alterou nada

[code]<?xml version="1.0" encoding="UTF-8"?>

<class name="loja.Produto" table="produto">

	<id name="id" type="integer" column="id">
                    <generator class="increment"/>
	</id>
	
	<property name="nome" type="string" column="nome"/>
            <property name="descricao" type="string" column="descricao"/>
            <property name="preco" type="float" column="preco"/>
            <property name="promocao" type="char" column="promocao"/>

	<set name="clientes"
		 table="pedido"
		 inverse="true">
		 
		<key column="fk_produto"/>
		<many-to-many class="loja.Cliente" column="fk_cliente"/>
		
	</set>

</class>

[/code]

pedido.hbm.xml - esse sofreu alteracoes

[code]<?xml version="1.0" encoding="UTF-8"?>

<class name="loja.Pedido" table="pedido">

	<composite-id name="id" class="loja.PedidoPK">
                 <key-property name="fk_produto" type="integer" column="fk_produto"/>
                 <key-property name="fk_cliente" type="integer" column="fk_cliente"/>
             </composite-id>
             
             <property name="quantidade" type="integer" column="quantidade"/>
            	
</class>

[/code]

E ainda criei a classe PedidoPK e alterei a classe Pedido

Pedido

[code]package loja;

import java.io.Serializable;

public class Pedido implements Serializable {

private PedidoPK id;
private Integer quantidade;

/** Creates a new instance of Pedido */
public Pedido() {
}

public Integer getQuantidade() {
    return quantidade;
}

public void setQuantidade(Integer quantidade) {
    this.quantidade = quantidade;
}

public PedidoPK getId() {
    return id;
}

public void setId(PedidoPK id) {
    this.id = id;
}

}[/code]

PedidoPK

[code]package loja;

import java.io.Serializable;

public class PedidoPK implements Serializable {

private Integer fk_produto;
private Integer fk_cliente;

/** Creates a new instance of PedidoPK */
public PedidoPK() {
}

public Integer getFk_produto() {
    return fk_produto;
}

public void setFk_produto(Integer fk_produto) {
    this.fk_produto = fk_produto;
}

public Integer getFk_cliente() {
    return fk_cliente;
}

public void setFk_cliente(Integer fk_cliente) {
    this.fk_cliente = fk_cliente;
}

}[/code]

A classe main:

[code]package loja;

import java.util.Date;
import org.hibernate.Session;
import org.hibernate.Transaction;

public class Teste {

public static void main(String[] args) {
    Session sessao = HibernateUtil.getSession(); //Abrindo uma sessão
    Transaction transaction = sessao.beginTransaction(); //Iniciando uma transação
    
    //Instaciando Produto
    Produto produto = new Produto(); 
    produto.setNome("joia");
    produto.setDescricao("joia de diamante");
    produto.setPreco(new Float(100));
    produto.setPromocao('n');
            
    //Instanciando cliente
    Cliente cliente = new Cliente();
    cliente.setNome("maria");
    cliente.setEndereco("rua bla bla");
    cliente.setBairro("bessa");
    cliente.setNumero(new Integer(10));
    cliente.setCidade("Joao Pessoa");
    cliente.setEstado("Paraiba");
    cliente.setCep("58034-240");
    cliente.setForma_pagamento("cartao");
    cliente.setInfo_pagamento("visa-01234567892");
    cliente.setData(new Date());
    
    //Insert em Produto e Cliente
    Integer idProduto = (Integer) sessao.save(produto);
    Integer idCliente = (Integer) sessao.save(cliente);
    transaction.commit();
    sessao.close();
                    
    sessao = HibernateUtil.getSession();
    transaction = sessao.beginTransaction();
    
    //Fazendo a associacao N:N entre Cliente e Produto e gravando na tabela Pedido
    produto = (Produto)sessao.get(Produto.class, idProduto);
    cliente = (Cliente)sessao.get(Cliente.class, idCliente);
    cliente.getProdutos().add(produto);
    produto.getClientes().add(cliente);

    PedidoPK pedidoPK = new PedidoPK();
    pedidoPK.setFk_cliente(idCliente);
    pedidoPK.setFk_produto(idProduto);
    
    Pedido pedido = new Pedido();
    //pedido.setFk_cliente(idCliente);
    //pedido.setFk_produto(idProduto);
    pedido.setId(pedidoPK);
    pedido.setQuantidade(new Integer(3));
            
    //Salvando tudo
    sessao.update(cliente);
    sessao.update(produto); 
    sessao.save(pedido);
            
    //persistente no banco de dados
    transaction.commit(); //Finalizando a transação
    sessao.close(); //Fechando a sessão
}

}[/code]

Erro:

14:07:17,936 DEBUG JDBCExceptionReporter:69 - Could not execute JDBC batch update [/* insert collection row loja.Cliente.produtos */ insert into pedido (fk_cliente, fk_produto) values (?, ?)] java.sql.BatchUpdateException: Entrada em lote 0 /* insert collection row loja.Cliente.produtos */ insert into pedido (fk_cliente, fk_produto) values (5, 8) foi abortada. Chame getNextException para ver a causa. at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2530) at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1317) at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:350) at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2592) at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:1723) at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48) at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:237) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:144) 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 loja.Teste.main(Teste.java:59) Exception in thread "main" org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71) at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43) at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:237) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:144) 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 loja.Teste.main(Teste.java:59) Caused by: java.sql.BatchUpdateException: Entrada em lote 0 /* insert collection row loja.Cliente.produtos */ insert into pedido (fk_cliente, fk_produto) values (5, 8) foi abortada. Chame getNextException para ver a causa. at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2530) at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1317) at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:350) at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2592) at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:1723) at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48) at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246) ... 8 more 14:07:17,967 WARN JDBCExceptionReporter:77 - SQL Error: 0, SQLState: null 14:07:17,967 ERROR JDBCExceptionReporter:78 - Entrada em lote 0 /* insert collection row loja.Cliente.produtos */ insert into pedido (fk_cliente, fk_produto) values (5, 8) foi abortada. Chame getNextException para ver a causa. 14:07:17,967 WARN JDBCExceptionReporter:77 - SQL Error: 0, SQLState: 23505 14:07:17,967 ERROR JDBCExceptionReporter:78 - ERROR: duplicate key violates unique constraint "pedido_pkey" 14:07:17,967 ERROR AbstractFlushingEventListener:301 - Could not synchronize database state with session org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71) at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43) at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:237) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:144) 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 loja.Teste.main(Teste.java:59) Caused by: java.sql.BatchUpdateException: Entrada em lote 0 /* insert collection row loja.Cliente.produtos */ insert into pedido (fk_cliente, fk_produto) values (5, 8) foi abortada. Chame getNextException para ver a causa. at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2530) at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1317) at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:350) at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2592) at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:1723) at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48) at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246) ... 8 more 14:07:18,014 DEBUG ConnectionManager:478 - registering flush end Java Result: 1

O mapeamento de Cliente e Produto continuam o msm da primeira pagina.
Nao sei pq ta dando esse erro.
Acho q n to acertando na hora de gravar. ALguem sabe oq ta errado?

Ae ate q enfim consegui, mas falta saber se estou fazendo pelo caminho correto, pela boa prática, eu mudei o main().

[code]package loja;

import java.util.Date;
import java.util.Iterator;
import org.hibernate.Session;
import org.hibernate.Transaction;

public class Teste {

public static void main(String[] args) {
    Session sessao = HibernateUtil.getSession(); //Abrindo uma sessão
    Transaction transaction = sessao.beginTransaction(); //Iniciando uma transação
    
    Produto produto = new Produto(); //Instanciando um objeto transiente
    produto.setNome("joia");
    produto.setDescricao("joia de diamante");
    produto.setPreco(new Float(100));
    produto.setPromocao('n');
            
    Cliente cliente = new Cliente();
    cliente.setNome("maria");
    cliente.setEndereco("rua bla bla");
    cliente.setBairro("bessa");
    cliente.setNumero(new Integer(10));
    cliente.setCidade("Joao Pessoa");
    cliente.setEstado("Paraiba");
    cliente.setCep("58034-240");
    cliente.setForma_pagamento("cartao");
    cliente.setInfo_pagamento("visa-01234567892");
    cliente.setData(new Date());
    
    Integer idProduto = (Integer) sessao.save(produto);
    Integer idCliente = (Integer) sessao.save(cliente);
    transaction.commit();
    sessao.close();
                    
    sessao = HibernateUtil.getSession();
    transaction = sessao.beginTransaction();
    
    PedidoPK pedidoPK = new PedidoPK();
    pedidoPK.setFk_cliente(idCliente);
    pedidoPK.setFk_produto(idProduto);
    
    Pedido pedido = new Pedido();
    pedido.setId(pedidoPK);
    pedido.setQuantidade(new Integer(3));
            
    //sessao.update(cliente);
    //sessao.update(produto); 
    sessao.save(pedido);
            
    //persistente no banco de dados
    transaction.commit(); //Finalizando a transação
    sessao.close(); //Fechando a sessão
    
    //testando os elementos cadastrados
    sessao = HibernateUtil.getSession();
    transaction = sessao.beginTransaction();
    
    produto = (Produto)sessao.get(Produto.class, idProduto);
    Iterator i = produto.getClientes().iterator();
    
    if (i.hasNext())
        cliente = (Cliente) i.next();
    
    System.out.println("Cliente Id: " + cliente.getId() + " Cliente Nome: " + cliente.getNome());
    
    sessao.close(); //Fechando a sessão
}[/code]

Oq mudou foi o seguinte, p salvar na tabela PEDIDO eu tenho agora 2 caminhos, o primeiro seria adicionar aos SET´s de CLIENTE e PRODUTO usando add() e dps dar upadate neles, mas ai n salvaria a QUANTIDADE. Ja o segundo metodo (o metodo usado e q salva a QUANTIDADE), eh popular o bean PEDIDO e PEDIDOPK e dar save nele. Qnd eu recupero o CLIENTE ou PRODUTO, ele ja vem c os SET´s associados, tanto q fiz um teste la em baixo e pegou blz. Tava dando pau antes pq eu tava tentando salvar pelo 2 modos duma vez so, por isso dava CONSTAINt VIOLATION EXCEPTION. Salvando so pelo BEAN PEDIDO atraves dum save nele pegou legal. Eh isso msm? Esse eh o modo correto? Vlw…

Fica como ajuda se alguem tiver msm problema…

como mandei pra vc como msg privada, eu uso uma classe separada para mapear a mapeamento com composite id.

outra coisa, do mapeamento many-to-many com um property na classe de mapeamento, vc deve fazer os set com one-to-many para a classe de associacao, assim como a classe de associacao tem um many-to-one para as outras duas classes.
Tipo esse set com a classe da minha classe contato com a classe instituicao, esse set esta na classe instituicao. Tenta fazer desse jeito.

    <set name="contatosInstituicao" inverse="true" cascade="save-update">
        <key column="`codigoInstituicao`"/>
        <one-to-many class="org.cronos.persistencia.bean.ContatoInstituicao"/>  
    </set>

rpz eu fiz o seguinte (e pegou), coloquei o na tabela do meio (Pedido) e dentro desta tag eu coloquei .

Eu nao usei <key-many-to-one name="propertyName class=“ClassName” column=“column_name”/>.

Nesse meu caso, eh mais correto usar o “key many to one”? Qual diferenca dele pro “key property”? O “key property” ta pegando td, inclusive a associacao qnd dou um list nas outras tabelas do relacionamento.