Como mapear classes no hibernate através de arquivos.xml

Estou com dúvida sobre mapeamentos!

Os dois trechos são de associações one to many, o primeiro exemplo é tirado deste link
http://www.xylax.net/hibernate/onetomany.html e representa o seguinte mapeamento:

Este é o código:

<class name="Foo" table="foo">
    ...
    <set role="bars" table="bar">
        <key column="foo_id"/>
        <one-to-many class="Bar"/>
    </set>
</class>

Já este outro exemplo faz a mesma coisa só que com tabelas diferentes, porém o mapeamento é de one-to-many:
Tabela cliente:

<class name='br.com.integrator.model.Cliente' table='clientes'>
...
<set  inverse='true' name='pedido'>
         <key column='clienteid_id' foreign-key='fk_pedidos_clienteid_key'/>
         <one-to-many class='br.com.integrator.model.Pedido' />
</set>

Tabela pedido:

<class name='br.com.integrator.model.Pedido' table='pedidos'>
      <id name='pedidoid' type='integer' column='pedidoid'>
         <generator class='native' />
      </id>
      <set  inverse='true' name='detalhesPedido'>
         <key column='pedidoid_id' foreign-key='fk_detalhes_pedido_pedidoid_key'/>
         <one-to-many class='br.com.integrator.model.DetalhesPedido' />
      </set>
      <many-to-one  foreign-key='fk_pedidos_clienteid_id' column='clienteid' class='br.com.integrator.model.Cliente' name='cliente' />
      <property  column='datapedido' type='date' name='datapedido'>
      </property>
   </class>

O 2º exemplo foi feito no netbeans, exemplo do livro do edson gonçalves.

Não entendo porque os comandos são diferentes.
Qual a necessidade do exemplo 2 especificar essa foreign-key? O primeiro exemplo não especificou pq?

O primeiro exemplo faz o mapeamento tão simples, já no segundo se torna um tanto quanto complicado, por exemplo:
esse trecho:

essa fk… eu escrevo o que quiser? pois na no sql nao existe nenhuma chave com esse nome, fk_pedidos_cli…

[code]

CREATE TABLE clientes (
ClienteID char(5) NOT NULL,
nome varchar(30) default NULL,
cargo varchar(30) default NULL,
endereco varchar(60) default NULL,
cidade varchar(15) default NULL,
cep varchar(10) default NULL,
pais varchar(15) default NULL,
telefone varchar(24) default NULL,
Fax varchar(24) default NULL,
PRIMARY KEY (ClienteID),
KEY cidade (cidade),
KEY cep (cep)
) [/code]

CREATE TABLE `pedidos` (
  `PedidoID` int(11) NOT NULL auto_increment,
  `ClienteID` char(5) default NULL,
  `dataPedido` datetime default NULL,
  PRIMARY KEY  (`PedidoID`),
  KEY `CustomerID` (`ClienteID`),
  CONSTRAINT `fk_clientes` FOREIGN KEY (`ClienteID`) REFERENCES `clientes` (`ClienteID`)
) 

up

Olá. Por que você não utiliza Annotations? Dê uma olhada na apostila FJ-28 da caelum. Abraços…

Usando o Annotations eu vou precisar desses dois arquivos?

<hibernate-configuration> <session-factory> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://192.168.0.2:3306/paroquia</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">123</property> <mapping class="minha classe" package="minha classe.hbm.xml" resource="minha classe.hbm.xml"/> </session-factory> </hibernate-configuration>

e deste:

[code]import org.hibernate.Session;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.SessionFactory;

public class IniciaHibernate {

private static final ThreadLocal<Session> tl = new ThreadLocal<Session>();
private static SessionFactory sf;

static {
    try {
        sf = new AnnotationConfiguration().configure("hibernate.cfg.xml").buildSessionFactory();
    } catch (Throwable ex) {
        // Log the exception. 
        System.err.println("Erro na classe IniciaHibernate.\n" + ex);
        throw new ExceptionInInitializerError(ex);
    }
}

public static Session getSession() {
    Session sessao = (Session)tl.get();
    sessao = sf.openSession();
    tl.set(sessao);
    return sessao;
}

}[/code]

[quote=moacirjava]Estou com dúvida sobre mapeamentos!

<class name="Foo" table="foo">
    ...
    <set role="bars" table="bar">
        <key column="foo_id"/>
        <one-to-many class="Bar"/>
    </set>
</class>

[/quote]

Ele estah fazendo um mapeamento onde ele referencia a tabela foo com a tabela Bar, e do qual ele estah criado uma lista da classe bar do qual eh chama de bars dentro da classe foo. E se ele nao colocou o package antes da classe eh pq as classes estah no mesmo package, entao nao ah necessidade de colocar todo o caminha da classe para referenciá-la. logo sua classe Bar ficaria algo assim:

Public classe Bar{
private Set<Bar> bars;

//metodos encapsuladores(gets e sets)

}
  1. Sim vc estah correto faz a mesma coisa, mas de uma maneira mais complexa e estranha. no caso uma outra maneira de mapear a lista ao meu ver seria assim:
//hbm
 <class name='br.com.integrator.model.Cliente' table='clientes'>  
 ... 
 <bag name="listPedido" table="TABELA_PEDIDO" inverse="true">
	<key>
		<column name="ID_CLIENTE" />
	</key>
	<one-to-many class="br.com.integrator.model.Pedido" />
 </bag>

//classe
Public classe Bar{
 private List<Pedido>listPedido;
  
 //metodos encapsuladores(gets e sets)
}
  1. Ele quis mostrar uma outra forma de mapear uma lista de Pedidos na classe Cliente usando foreign-key(do qual serah necessario nesse caso).

  2. Idem resposta 2

  1. Não vc nao escre oq quiser vc apenas vai referenciar a chave estrangeira com a chave primaria. Olha exemplo que te passei acima acho q estah mais claro.

  2. Sim existe, toda vez que vc cria uma chave estrangeira para referenciar uma tabela com a outra elA irá criar uma constraint foreign key na sua tabela com as iniciais FK+NOME_DA_TABELA_DESTINO+NOME_DA_TABELA_ORIGEM.

[quote=moacirjava]Usando o Annotations eu vou precisar desses dois arquivos?

<hibernate-configuration> <session-factory> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://192.168.0.2:3306/paroquia</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">123</property> <mapping class="minha classe" package="minha classe.hbm.xml" resource="minha classe.hbm.xml"/> </session-factory> </hibernate-configuration>
[/quote]

O arquivo hibernate.cfg.xml vc sempre vai ter independente de estar usando annotations ou não, pois eh nela que vc vai dizer no caso das anotações quais sao classes e serem mapeadas, se for o hbm vai dizer quais sao os arquivo .hbm.xml a serem mapeados. Esse arquivo por default fica na raiz da sua pasta src ou JavaSource.

[quote=moacirjava]
e deste:

[code]import org.hibernate.Session;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.SessionFactory;

public class IniciaHibernate {

private static final ThreadLocal<Session> tl = new ThreadLocal<Session>();
private static SessionFactory sf;

static {
    try {
        sf = new AnnotationConfiguration().configure("hibernate.cfg.xml").buildSessionFactory();
    } catch (Throwable ex) {
        // Log the exception. 
        System.err.println("Erro na classe IniciaHibernate.\n" + ex);
        throw new ExceptionInInitializerError(ex);
    }
}

public static Session getSession() {
    Session sessao = (Session)tl.get();
    sessao = sf.openSession();
    tl.set(sessao);
    return sessao;
}

}[/code][/quote]

Classe responsável pela configuração do Hibernate Annotations. Tbm eh necessário usá-lo pois eh melhor vc declarar a classe uma unica vez na qual vc sempre vai utilizar na sua aplicação. vc nao vai ficar criando o código acima toda vez q precisar nao eh?

Melhorando o código acima:

import org.hibernate.*;
import org.hibernate.cfg.*;

public class HibernateUtil {

	private static SessionFactory sessionFactory;

	static {
		try {
			sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
		} catch (Throwable ex) {		
			System.err.println("Initial SessionFactory creation failed." + ex);
			throw new ExceptionInInitializerError(ex);
		}
	}

	public static SessionFactory getSessionFactory() {
		if(sessionFactory == null){
			try {
				sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
			} catch (Throwable ex) {	
				System.err.println("Initial SessionFactory creation failed." + ex);
				throw new ExceptionInInitializerError(ex);
			}
		}
		return sessionFactory;
	}
} 

Usando annotations dá pra utilizar a Criteria pra construir consultas personalizadas? Li na net o pessoal dizendo que é ruim.

Sim da para usar normalmente vc pode criar sua classes DAO >> BO >> Proxy >> Interface e fazer os metodos de persitencia ao banco de dados, mas eu prefiro usar HQL.
De uma olhada aqui talvez te ajude a entender melhor sobre Criteria, HQL e Querie Nativa. Boa sorte!

[quote=ebarros]
Sim da para usar normalmente vc pode criar sua classes DAO >> BO >> Proxy >> Interface e fazer os metodos de persitencia ao banco de dados, mas eu prefiro usar HQL.
De uma olhada http://javafree.uol.com.br/topic-871797-Dicas-e-Discussoes-sobre-HQL-Criteria-e-Query-Nativa.html]aqui talvez te ajude a entender melhor sobre Criteria, HQL e Querie Nativa. Boa sorte![/quote]

Realmente, to lendo aqui, parece ser mais fácil mesmo…