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

12 respostas
warcanjow

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.

warcanjow

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());  
}
warcanjow

É 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.

warcanjow

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!

warcanjow

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!

warcanjow

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.

warcanjow

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.

warcanjow

Consegui, ta tudo rodando perfeitamente!

obrigado!

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