[Resolvido]Problemas com Hibernate + PostgreSQL -> select nextval ('')

12 respostas
W

Olá pessoal!

Estou iniciando no hiernate e me deparei com um probleminha chato que ja me fez perder muitas horas. A grosso modo não consigo fazer inserções no banco de dados postgre com uma id auto-incrementada. Tenho a seguinte classe produto:

package repositorios;

public class Produtos {
	
	protected long id;
	protected String nome;
	protected double vlrVenda;
	protected double percASVendas;
	
	public Produtos(){
		
	}
	
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getNome() {
		return nome;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}
	public double getVlrVenda() {
		return vlrVenda;
	}
	public void setVlrVenda(double vlrVenda) {
		this.vlrVenda = vlrVenda;
	}
	public double getPercASVendas() {
		return percASVendas;
	}
	public void setPercASVendas(double percASVendas) {
		this.percASVendas = percASVendas;
	}
	
	
}
Uma classe de teste:
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import repositorios.Produtos;

public class TesteIncHibernate {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		Session session = null;
		System.out.println("criou sessão");
		
		try{
			
			SessionFactory sessionfactory = new Configuration().configure().buildSessionFactory();
			session = sessionfactory.openSession();
			Produtos produto = new Produtos();
			System.out.println("criou o objeto");
			produto.setNome("teste");
			produto.setPercASVendas(15);
			produto.setVlrVenda(12);
			System.out.println("setou valores");
			session.save(produto);
			System.out.println("salvou");
		}catch(Exception e){
			System.out.println(e.getMessage());
		}

	}

}

O seguinte mapeamento 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>
  <class name="repositorios.Produtos" table="Produtos">
	   <id name="id" type="long" column="ID" >
	   <generator class="sequence">
	   		<param name="sequence">produto_id</param>
	   </generator>
	  </id>

	  <property name="nome">
		 <column name="nome" />
	  </property>
	  <property name="vlrVenda">
		<column name="vlrVenda"/>
	  </property>
	  <property name="percASVendas">
		<column name="percASVendas"/>
	  </property>
   </class>

</hibernate-mapping>

e o hibernate.cfg.xml:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
      <property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
      <property name="hibernate.connection.url">jdbc:postgresql://localhost/SimplesBD</property>
      <property name="hibernate.connection.username">jackson</property>
      <property name="hibernate.connection.password">root</property>
      <property name="hibernate.connection.pool_size">10</property>
      <property name="show_sql">true</property>
      <property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
      <property name="hibernate.hbm2ddl.auto">update</property>
      <!-- Mapping files -->
      <mapping resource="simples.hbm.xml"/>
</session-factory>
</hibernate-configuration>

Quando executo a classe de teste recebo a seguinte saida:

criou o objeto
setou valores
Hibernate: select nextval ('produto_id')
salvou

ou seja, executa tudo, mas ocorre um erro em tempo de execução "Hibernate: select nextval ('produto_id')". Quando olho no banco a sequnce que criei é incrementada em 1, mas nenhum registro é adicionado a tabela de produtos. Alguém sabe como posso fazer para conseguir adicionar dados na tabela com uma id auto-increment?

Estou utilizando o eclipse galileo com postgre 8 e hibernate 3.

Abraço!

12 Respostas

H

Se você estive usando Annotations você poderia fazer assim.

@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="generator")
@SequenceGenerator(name="generator", sequenceName="produto_id_seq", allocationSize=1)
@Column(name="id")	
public Long getId() {
	return this.id;
}

Nunca fiz mapeamento com xml.
Te aconselho a usar anotações, é muito mais produtivo. Se você der uma pesquisada verá que anotações é melhor.

Outra coisa que percebi.
Você tem que abrir uma transação e comitar.

try{  
              
     SessionFactory sessionfactory = new Configuration().configure().buildSessionFactory();  
     session = sessionfactory.openSession();
     Transaction tx = session.beginTransaction(); // faltou isso
     Produtos produto = new Produtos();  
     System.out.println("criou o objeto");  
     produto.setNome("teste");  
     produto.setPercASVendas(15);  
     produto.setVlrVenda(12);  
     System.out.println("setou valores");  
     session.save(produto);
     tx.commit(); // faltou isso  
     System.out.println("salvou");  
}catch(Exception e){
     tx.rollback(); // faltou isso
     System.out.println(e.getMessage());  
}

Espero ter ajudado.

W

Basta que eu coloque essas anotações no bean e mais nada?

henriquejhc:

@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="generator")
@SequenceGenerator(name="generator", sequenceName="produto_id_seq", allocationSize=1)
@Column(name="id")	
public Long getId() {
	return this.id;
}

.

H

Altera onde está faltando.

try{  
              
     SessionFactory sessionfactory = new Configuration().configure().buildSessionFactory();  
     session = sessionfactory.openSession();
     Transaction tx = session.beginTransaction(); // faltou isso
     Produtos produto = new Produtos();  
     System.out.println("criou o objeto");  
     produto.setNome("teste");  
     produto.setPercASVendas(15);  
     produto.setVlrVenda(12);  
     System.out.println("setou valores");  
     session.save(produto);
     tx.commit(); // faltou isso  
     System.out.println("salvou");  
}catch(Exception e){
     tx.rollback(); // faltou isso
     System.out.println(e.getMessage());  
}
W

É preciso fazer algum import?

No bean as anotations estão marcadas de vermelho(can’t be resolved a type, segundo o eclipse) e o tx.rollback() na classe de teste também fica do mesmo jeito. Comentei o tx.rollback() o programa executou, mas imprimiu a seguinte saida:

criou sessão
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
Exception occurred inside getter of repositorios.Produtos.id

Alguma idéia???

Desde já muito obrigado pela ajuda!

H

Você mudou os mapementos para anotações?

Import na classe teste:

import org.hibernate.Transaction;

Esses avisos:
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
Não são erros.

Os imports para o bean:

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;

Se você for usar anotações avisa.

Espero ter ajudado.

W

Estou tentando com anotations sim. Fiz as modificações que você sugeriu, mas o sproblemas persistiram. Pesquisei um pouco e vi que para poder usar as anotations é necessário no mínimo o Hibernate Core 3.2.0GA, como estava utilizando o 3.0 estou tentando migrar pra ver se era esse o problema. Daqui a pouco posto o resultado.

Abraço!

W

opa! O problema não foi resolvido ainda, mas ja temos uma evolução depois que modifiquei a versão do hibernate.

Todos os problemas do bean Produtos foram resolvidos, mas a classe de teste continua sem aceitar o “tx.rollback();”. quando rodei foi feita a inclusão no banco. No entando a resposta que tive no console foi a seguinte:

criou sessão

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).

log4j:WARN Please initialize the log4j system properly.

criou o objeto

setou valores

Hibernate: select nextval (‘produto_id’)

Hibernate: insert into Produtos (nome, vlrVenda, percASVendas, ID) values (?, ?, ?, ?)

salvou

alguma idéia??

Abraço!

W

Correção: a mensagem “Hibernate: select nextval (‘produto_id’)” não é um erro é apenas uma informação. Só vim perceber depois de debugar o códiog com mais calma. A unica questão agora é o tx.rollback() que fica com a mesnsagem (can’t resolved type).

H
// coloca essas linhas fora do try
SessionFactory sessionfactory = new Configuration().configure().buildSessionFactory();  
session = sessionfactory.openSession();
Transaction tx = session.beginTransaction();
try{      
     Produtos produto = new Produtos();  
     System.out.println("criou o objeto");  
     produto.setNome("teste");  
     produto.setPercASVendas(15);  
     produto.setVlrVenda(12);  
     System.out.println("setou valores");  
     session.save(produto);
     tx.commit(); 
     System.out.println("salvou");  
}catch(Exception e){
     tx.rollback(); 
     System.out.println(e.getMessage());  
}

Qualquer duvida coloca ai.
Espero ter ajudado.

W

fazendo assim eu fico sem tratamento de exceção para as instâncias, mas não acho que vá ser um grande prejuizo.

Cara muito obrigado. Valeu mesmo pelas dicas.

Abraço!

H

Você está tratando sim. Você tem uqe tratar o mais importante que é momento em que ele salva.

Conseguiu resolver?

Espero ter ajudado.

W

Consegui, ta tudo rodando perfeitamente!

obrigado!

Criado 16 de fevereiro de 2010
Ultima resposta 16 de fev. de 2010
Respostas 12
Participantes 2