Pobre iniciante em hibernate pedindo ajuda :(

Aqui está o meu hibernate.cfg.xml

[code]
<?xml version=‘1.0’ encoding=‘utf-8’?>
<!DOCTYPE hibernate-configuration PUBLIC “-//Hibernate/Hibernate Configuration DTD//EN” “http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd”>
<hibernate-configuration>
<session-factory>
<property name=“hibernate.connection.driver_class”>org.firebirdsql.jdbc.FBDriver</property>
<property name=“hibernate.connection.url”>jdbc:firebirdsql:localhost/3050:G:/Projetos/Agenda/banco/agenda.gdb</property>
<property name=“hibernate.connection.username”>SYSDBA</property>
<property name=“hibernate.connection.password”>masterkey</property>
<property name=“show_sql”>true</property>
<property name=“dialect”>org.hibernate.dialect.FirebirdDialect</property>

	&lt;mapping resource="mapContato.xml"/&gt;
&lt;/session-factory&gt;

</hibernate-configuration>

Arquivo mapContato.xml:
<?xml version=“1.0” encoding=“UTF-8” ?>
<!DOCTYPE hibernate-mapping PUBLIC “-//Hibernate/Hibernate Mapping DTD 2.0//EN” “http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd”>
<hibernate-mapping>
<class name=“magno.agenda.tabelas.Contato” table=“Contato”>
<id name=“id”>
<generator class=“increment” />
</id>
<property name=“nome”/>
<property name=“dataNasc”/>
<property name=“telRes”/>
<property name=“telCom”/>
<property name=“telCel”/>
</class>
</hibernate-mapping>

Arquivo Contato.java:
package magno.agenda.tabelas;

import java.util.Date;

public class Contato {
private long id;
private Date dataNasc;
private String nome, telRes, telCom, telCel;

public Contato() {}

public long getId() {
    return id;
}

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

public Date getDataNasc() {
    return dataNasc;
}

public void setDataNasc(Date dataNasc) {
    this.dataNasc = dataNasc;
}

public String getNome() {
    return nome;
}

public void setNome(String nome) {
    this.nome = nome;
}

public String getTelRes() {
    return telRes;
}

public void setTelRes(String telRes) {
    this.telRes = telRes;
}

public String getTelCom() {
    return telCom;
}

public void setTelCom(String telCom) {
    this.telCom = telCom;
}

public String getTelCel() {
    return telCel;
}

public void setTelCel(String telCel) {
    this.telCel = telCel;
}

}

Arquivo Inicio.java(Aonde ocorre o inicio da aplicação… por enquanto eu só tentei inserir um codigo no main() mesmo, para tentar usar o hibernate):
Aqui está o meu hibernate.cfg.xml
[code]
<?xml version=‘1.0’ encoding=‘utf-8’?>
<!DOCTYPE hibernate-configuration PUBLIC “-//Hibernate/Hibernate Configuration DTD//EN” “http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd”>
<hibernate-configuration>
<session-factory>
<property name=“hibernate.connection.driver_class”>org.firebirdsql.jdbc.FBDriver</property>
<property name=“hibernate.connection.url”>jdbc:firebirdsql:localhost/3050:G:/Projetos/Agenda/banco/agenda.gdb</property>
<property name=“hibernate.connection.username”>SYSDBA</property>
<property name=“hibernate.connection.password”>masterkey</property>
<property name=“show_sql”>true</property>
<property name=“dialect”>org.hibernate.dialect.FirebirdDialect</property>

	&lt;mapping resource="mapContato.xml"/&gt;
&lt;/session-factory&gt;

</hibernate-configuration>

Arquivo mapContato.xml:
<?xml version=“1.0” encoding=“UTF-8” ?>
<!DOCTYPE hibernate-mapping PUBLIC “-//Hibernate/Hibernate Mapping DTD 2.0//EN” “http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd”>
<hibernate-mapping>
<class name=“magno.agenda.tabelas.Contato” table=“Contato”>
<id name=“id”>
<generator class=“increment” />
</id>
<property name=“nome”/>
<property name=“dataNasc”/>
<property name=“telRes”/>
<property name=“telCom”/>
<property name=“telCel”/>
</class>
</hibernate-mapping>

Arquivo Contato.java:
package magno.agenda.tabelas;

import java.util.Date;

public class Contato {
private long id;
private Date dataNasc;
private String nome, telRes, telCom, telCel;

public Contato() {}

public long getId() {
    return id;
}

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

public Date getDataNasc() {
    return dataNasc;
}

public void setDataNasc(Date dataNasc) {
    this.dataNasc = dataNasc;
}

public String getNome() {
    return nome;
}

public void setNome(String nome) {
    this.nome = nome;
}

public String getTelRes() {
    return telRes;
}

public void setTelRes(String telRes) {
    this.telRes = telRes;
}

public String getTelCom() {
    return telCom;
}

public void setTelCom(String telCom) {
    this.telCom = telCom;
}

public String getTelCel() {
    return telCel;
}

public void setTelCel(String telCel) {
    this.telCel = telCel;
}

}

Arquivo Inicio.java(Aonde ocorre o inicio da aplicação… por enquanto eu só tentei inserir um codigo no main() mesmo, para tentar usar o hibernate):
package magno.agenda;

import java.sql.*;

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

public class Inicio {
public static void main(String[] args) throws Exception {
SessionFactory sf = null;
try {
Configuration cfg = new Configuration().configure();
sf = cfg.buildSessionFactory();
}
catch(HibernateException he) {
he.printStackTrace();
}
Session s = sf.openSession();
magno.agenda.tabelas.Contato c = new magno.agenda.tabelas.Contato();
c.setId(3);
c.setNome(“Magno Machado Paulo”);
s.saveOrUpdate©;
s.connection().commit();
s.close();
}
}

[/code]

Se eu bem entendi o esquema do hibernate, então agora era pra ter um registro na minha tabela Contatos contendo o id 3 e nome “Magno Machado Paulo”, estou certo? Bom… o lance é que nenhum registro apareceu na minha tabela.
Quando rodo esse código, a unica saída que eu obtenho na tela é:

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.

Ah, sim, e aqui está o script da minha tabela(Utilizo firebird 1.5)
[code]
/* Tabela: CONTATOS */

CREATE TABLE CONTATOS (
NOME VARCHAR (30) CHARACTER SET WIN1251 NOT NULL COLLATE WIN1251,
“dataNasc” DATE,
“telRes” CHAR (10) CHARACTER SET WIN1251 COLLATE WIN1251,
“telCom” CHAR (10) CHARACTER SET WIN1251 COLLATE WIN1251,
“telCel” CHAR (10) CHARACTER SET WIN1251 COLLATE WIN1251,
ID BIGINT NOT NULL);

/* Primary keys definition */

ALTER TABLE CONTATOS ADD CONSTRAINT PK_CONTATOS PRIMARY KEY (ID);

/* Indices definition */

CREATE UNIQUE INDEX PK_CONTATOS ON CONTATOS (ID);
[/code]

Acho que não é um problema especifico do banco de dados ou do driver utilziado, visto que eu consegui inserir dados na tabela criando uma conexão diretamente via jdbc…

(Desculpem, sei que a msg ficou mto grande, mas acho que não daria para alguem me ajudar sem eu ter postado todo esse codigo…)

Bem cara…

vamos por partes

1º - No arquivo hibernate.properties, procure a seguinte linha e descomente esta opção.

[code]##############################

Miscellaneous Settings

##############################

print all generated SQL to the console

----->>>> #hibernate.show_sql true
#Descomente esta linha acima.
[/code]

Isso faz com que o container exiba o código sql pra você.
Ajuda na hora de saber se inseriu ou não.

2º - Os mapas dos arquivos devem ter nome do arquivo seguidos de extensão .hbm.xml (você colocou cfg.xml). Acho que confundiu algo.
Coloque as extensões dos mapas como .hbm.xml

3º - Para o PostgreeSQL é necessário usar transactions. Talvez para o FireBird seja necessário tb. Vou postar um exemplo do uso de transactions:

[code]public class AlunoService{
static Session s;
public static void salvar(Aluno a)
{
try{
s = HibernateManager.factory.openSession();
Transaction tx= s.beginTransaction();
s.save(a);
tx.commit();
s.close();
}catch(Exception e){
e.printStackTrace();
}
}
public static void excluir(Aluno a)
{
try{
s = HibernateManager.factory.openSession();
Transaction tx= s.beginTransaction();
s.delete(a);
tx.commit();
s.close();
}catch(Exception e){
e.printStackTrace();
}
}

public static List consultar&#40;&#41;
	&#123;
	List alunos= new Vector&#40;&#41;;
	try
	   &#123;
		s = HibernateManager.factory.openSession&#40;&#41;;
		Transaction tx= s.beginTransaction&#40;&#41;;
		alunos = s.find&#40;&quot;from Aluno as aluno&quot;&#41;;
		tx.commit&#40;&#41;;
		s.close&#40;&#41;;
	   &#125;
	catch&#40;Exception e&#41;
	&#123;
	e.printStackTrace&#40;&#41;;
    &#125;
	return alunos;
	&#125; 

}[/code]

Este exemplo é uma classe de serviços para o Hibernate. Isso inclui, salvar, excluir e listar registros. Deve te ajudar.

4º - É legal você separar os serviços do resto do código.
Por isso, faça as classes beans como você fez, mas na hora de executar alguma operação, separe em uma outra classe, como essa que eu fiz.

5º - No Hibernate é assim mesmo, no meu caso eu estava em uma turma quando aprendia a usar o hib, e o professor disse que eum conseguisse inserir primeiro ganhava um cerveja. Eu ganhei… Mas o interessante é que isso mostra que é dificil fazer funcionar na 1ª. Em compensação
depois disso eu consegui fazer excluir e Listar sem maiores esforços.

6º - Por fim vou postar uma classe que gerencia o acesso ao Hibernate.

[code]import net.sf.hibernate.cfg.Configuration;
import net.sf.hibernate.SessionFactory;

public class HibernateManager {
static boolean teste=false;
static SessionFactory factory;
public static void configure(){
try{
if(teste==false){
Configuration cfg = new Configuration().addClass(Aluno.class);
factory = cfg.buildSessionFactory();
teste=true;
}

&#125;catch &#40;Exception e&#41;&#123;
	e.printStackTrace&#40;&#41;;
&#125;
&#125;

}[/code]

e um exemplo de mapa.

O nome deste arquivo abaixo é ALUNO_HBM.XML

[code]

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD/EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="br.portalcon.hiber.Aluno" table="alunos">
<id name="id" type="int">
<column name="id" not-null="true"/>
<generator class="assigned"/>
</id>
<property name="nome">
<column name="nome" length="30" not-null="false"/>
</property>

&lt;property name=&quot;idade&quot;&gt;
 	&lt;column name=&quot;idade&quot; length=&quot;15&quot; not-null=&quot;false&quot;/&gt;
&lt;/property&gt;

</class>
</hibernate-mapping>[/code]

Dá uma verificada e veja se o padrão está igual. Pq os caras do Hibernate sempre mudam e não me avisam. rss…

Abaixo tem a classe bean que eu usei neste projeto.
Repare que ela é simples e básica, usada apenas representar dados.

[code]
public class Aluno{
String nome;
Integer idade;
Integer id;

public String getNome&#40;&#41;  &#123; return nome; &#125;
public Integer getIdade&#40;&#41;&#123; return idade; &#125;
public Integer getId&#40;&#41;      &#123; return id; &#125;
    
public void setNome&#40;String s&#41;    &#123; nome = s;&#125;
public void setIdade &#40;Integer i&#41;  &#123; idade = i;&#125;
public void setId &#40;Integer cod&#41;   &#123; id = cod;&#125;

}[/code]

Força pra você, e não desista que vc consegue.

té +

so um detalhe, essa mensagem é normal aparecer

log4j&#58;WARN No appenders could be found for logger &#40;org.hibernate.cfg.Environment&#41;. log4j&#58;WARN Please initialize the log4j system properly.

:wink:

Poisé, o problema todo estava nas transactions. Reescrevi o código usando transactions, me baseando no seu exemplo, e funcionou :wink:
Valeu ae!!
Mas… Então para alguns bancos é obrigatorio o uso de transactions, e em outros isso é facultativo? Pensei que o hibernate fosse totalmente transparente no que diz respeito ao banco de dados utilizado :frowning:

[quote=“feliperod”]4º - É legal você separar os serviços do resto do código.
Por isso, faça as classes beans como você fez, mas na hora de executar alguma operação, separe em uma outra classe, como essa que eu fiz.
[/quote]
Como assim?
Então nesse meu exemplo, eu deveria fazer uma ‘classe de serviço’(é esse o nome) para os contatos, que seria uma classe com métodos para inserir, remover e listar os contatos? é isso?

editado: foi mal, só agora eu vi que na propria msg sua já havia a resposta pra essa pergunta :wink:

dreh_es, e tem como fazer para não aparecer essa msg?

Que bom que deu certo…

Pois é, em alguns bancos temos que usar transactions obrigatóriamente. Mas com a experiência isso se torna simples. Ou podemos tb usar transactions para todos os banco que trabalharmos. Mas quando der algum problema desse tipo, fica fácil de testar se é o caso de se usar transactions.

Bem, podemos tb fazer uma lista de bancos que usam transactions e deixar on-line… Já conhecemos 2, o PostgreeSQL e o FireBird

Quanto à classe de serviços, repare que eu usei uma classe para gerenciar o acesso ao Hibernate (hibernateManager), outra para realizar as operações tb chamados de serviços(AlunoService) e outra para representar a tabela Alunos (Aluno). Isso fornece maior controle sobre seu código e maior clareza no mesmo.

Qualquer dúvida estou à disposição…

té +

Ô Felipe, você também usa Struts? Preciso trocar umas idéias.

Retirado de hibernate.org

Are there known issues with Interbase / Firebird?

(Michael Jakl)

Yes. Due to some limitations in Interbase / Firebird we must use some workarounds:

Always set the size of your statement cache to zero (hibernate.statement_cache.size or hibernate.c3p0.max_statements)

If you are altering tables you should be in single user mode. This can be achieved by running gfix -shut. It’s also sufficient to have only one database connection open (eg. immediately after starting the application). If more than one connection is open, you will see errors like “table is in use”. To restart your database use gfix -online.

Uso Struts sim…

Qual é a dúvida???

Estou à disposição…