Problema com @GeneratedValue

8 respostas
M

Olá pessoal tenho um erro e uma duvida

o erro é o seguinte:

Hibernate: 
    select
        nextval ('hibernate_sequence')
1740 [main] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 0, SQLState: 42P01
1740 [main] ERROR org.hibernate.util.JDBCExceptionReporter - ERRO: relação "hibernate_sequence" não existe
  Posição: 17
Não foi possivel inserir o contato. Erro: could not get next sequence value

Esse erro aconteceu após eu construir uma classe mapeada com annotations para utilizar o hibernate 3.5.2

Sendo ela :

package com.crud;

import java.sql.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "contato")
public class Contato {
	
	@Id
	@GeneratedValue
	@Column(name = "codigo")
	private Integer codigo;
	
	@Column(name ="nome", length=50, nullable=true)
	private String nome;
	
	@Column(name="telefone", length=50, nullable=true)
	private String telefone;
	
	@Column(name="email", length=50, nullable=true)
	private String email;
	
	@Column(name="data_cad", nullable=true)
	private Date dataCadastro;
	
	@Column(name="obs", nullable=true)
	private String observacao;
	
	public Integer getCodigo() {
		return codigo;
	}
	public void setCodigo(Integer codigo) {
		this.codigo = codigo;
	}
	public String getNome() {
		return nome;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}
	public String getTelefone() {
		return telefone;
	}
	public void setTelefone(String telefone) {
		this.telefone = telefone;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public Date getDataCadastro() {
		return dataCadastro;
	}
	public void setDataCadastro(Date dataCadastro) {
		this.dataCadastro = dataCadastro;
	}
	public String getObservacao() {
		return observacao;
	}
	public void setObservacao(String observacao) {
		this.observacao = observacao;
	}

}

Tabela no banco:

Create Sequence ss; //gambi para fazer a auto incrementacao

CREATE TABLE contato
(
  codigo integer NOT NULL DEFAULT nextval('ss'),
  nome character varying(100) NOT NULL,
  telefone character varying(30) NOT NULL,
  email character varying(30) NOT NULL,
  data_cad date,
  obs character varying(255),
  CONSTRAINT pk_codigo PRIMARY KEY (codigo )
)

Esse erro pode estar sendo causado pelo fato do postgreSQL não usar aquele auto_increment que tem no MySql?
no livro que peguei essas annotations o cara usa como exemplo o banco de dados MySql

8 Respostas

edubiss

Mathe,

Com o PostgreSQL eu criava a sequence no banco e depois usava ela na minha entidade. Para isso, você pode usar a anotação na classe:

@Entity @Table(name = "contato") @SequenceGenerator(name = "nome_sequence", sequenceName = "nome_da_sequence_criada_no_banco") public class Contato

Depois no teu atributo Id da entidade, tu referencia essa sequence assim:

@Id @GeneratedValue(strategy = GenerationType.AUTO, generator = "nome_sequence") @Column(name = "codigo") private Integer codigo;

Minhas entidades com o banco PostgreSQL funcionam perfeitamente assim. Tenta ai dessa forma.

M

edubiss:
Mathe,

Com o PostgreSQL eu criava a sequence no banco e depois usava ela na minha entidade. Para isso, você pode usar a anotação na classe:

@Entity @Table(name = "contato") @SequenceGenerator(name = "nome_sequence", sequenceName = "nome_da_sequence_criada_no_banco") public class Contato

Depois no teu atributo Id da entidade, tu referencia essa sequence assim:

@Id @GeneratedValue(strategy = GenerationType.AUTO, generator = "nome_sequence") @Column(name = "codigo") private Integer codigo;

Minhas entidades com o banco PostgreSQL funcionam perfeitamente assim. Tenta ai dessa forma.

Poisé velho essa solução ai funcionou, eu acabei de encontrar outra melhor ainda, criar uma sequencia no postgreSql com o nome de hibernate_sequence, depois disso eu posso continuar fazendo as annotations normalmente como:

@Entity
@Table(name = "contato")
public class Contato {
	
	@Id
	@GeneratedValue
	@Column(name = "codigo")
	private Integer codigo;

É menos código mas ai eu não poderia escolher o nome da sequencia la no postgre.

edubiss

Legal cara, se o PostgreSQL não reclamar de nomes de sequence iguais entre as tabelas, dá pra usar :slight_smile:

M

Não reclama não da pra usar, agora só não sei se por exemplo

a sequence foi criada em uma tabela e nessa tabela ela ja ta no valor 120 por exemplo, se eu usar ela em outra tabela ela não vai começar pelo 120?

M

Não acho uma boa prática utilizar esta hibernate_sequence. Crie sequences pras suas tabelas e as utilize.

M

Porque não seria uma boa pratica ajuda a diminuir o código nas classes crud

R

Boa pratica é voce usar sequence pra cada tabela. Manutenção é um dos beneficios disso.

A

No arquivo hibernate.hbm.xml, onde você mapeia suas classes, tem que modificar o atributo do gerador de id da sua classe, por exemplo:

<class name="entidades.Permissoes" table="spring.permissoes"> <id name="idPermissoes" type="long" column="id_permissoes" > <generator class="identity"/> </id> <property name="usuario" type="string" column="usuario" /> <property name="permissao" type="string" column="permissao" /> </class>

na tag normalmente você coloca o valor “assigned”, que informa que é a aplicação quem vai setar o id, então modifique-o para identity. Dessa forma o hibernate vai usar a sequencia do banco!

Da uma olhada nesse link pra ver o que cada atributo dessa tag pode fazer:
http://www.roseindia.net/hibernate/hibernateidgeneratorelement.shtml

Criado 23 de novembro de 2012
Ultima resposta 31 de jan. de 2014
Respostas 8
Participantes 5