JPA - @GeneratedValue, como fazer?

22 respostas
fredferrao

Galera to apanhando aqui pra fazer o exemplo da JavaMagazine da Java Persistence API, na revista ele usa o MySQL e o Generated assim:

@GeneratedValue(strategy = GenerationType.IDENTITY)

Mau eu estou tentando fazer com o PostGres e gostaria de usar com SEQUENCE, fiz assim:

@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="cliente_sequence")

mas da o seguinte erro:
org.postgresql.util.PSQLException: ERROR: null value in column “cd_cliente” violates not-null constraintError Code: 0
Call:INSERT INTO locadora.CLIENTE (DS_NOME, DS_ENDERECO) VALUES (?, ?)
bind => [André, Bahia]

parece que a JPA nao pega a sequence e joga no campo codigo, ai da erro not null.

Qual a maneira de mapear pra usar o ID como SEQUENCE, especificando o nome da SEQUENCE??

vlw!!

22 Respostas

urubatan

tem que colocar uma outra anotação junto para criar a sequence, não lembro agora qual é, da uma olhada no javadoc que t acha, caso contrario amanha do uma olhada nisto :smiley:

tiagogn

Olá,

A anotação que e nosso amigo citou é essa aqui:

@Id
	@SequenceGenerator( name = "CLIENTE_ID", sequenceName = "CLIENTE_SEQ", allocationSize = 1 )
	@GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "CLIENTE_ID" )
	@Column( name = "ID", nullable = false )
	private Long id;

falow, ate+

fredferrao

Blz, a noite vou testar la em casa e posto aqui, maaass eu tinha tentado fazer com essa annotation, mas nao tinha colocado esse allocationsize, sera que foi isso?

fredferrao

Galera, funcionou nao em, olhem so:

Cliente.java

package testejapa;

import java.io.Serializable;
import javax.persistence.*;

/**
 *
 * @author Administrador
 */
@Entity
public class Cliente implements Serializable {
    @Id
    @SequenceGenerator(name = "CLIENTE_ID", sequenceName = "CLIENTE_SEQUENCE", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "CLIENTE_ID")
    @Column(name = "CODIGO", nullable = false)
    private Integer codigo;
    
    @Column(name = "NOME")
    private String nome;

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
  <persistence-unit name="teste" transaction-type="RESOURCE_LOCAL">
    <provider>oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider</provider>
    <class>testejapa.Cliente</class>
    <properties>
      <property name="toplink.jdbc.url" value="jdbc:postgresql://localhost:5432/postgres"/>
      <property name="toplink.jdbc.user" value="postgres"/>
      <property name="toplink.jdbc.driver" value="org.postgresql.Driver"/>
      <property name="toplink.jdbc.password" value="*****"/>
    </properties>
  </persistence-unit>
</persistence>

orm.xml

<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" version="1.0">
    <persistence-unit-metadata>
        <persistence-unit-defaults>
            <schema>fred</schema>
        </persistence-unit-defaults>
    </persistence-unit-metadata>
</entity-mappings>

BD

CREATE TABLE fred.cliente
(
  codigo int8 NOT NULL,
  nome varchar(50) NOT NULL,
  CONSTRAINT cliente_pkey PRIMARY KEY (codigo)
) 

*************

sequence

CREATE SEQUENCE fred.cliente_sequence
  INCREMENT 1
  MINVALUE 1
  MAXVALUE 999999999999
  START 1
  CACHE 1;

e ainda da erro:

Exception in thread "main" javax.persistence.RollbackException: Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2006.8 (Build 060830)): oracle.toplink.essentials.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: null value in column "codigo" violates not-null constraintError Code: 0
Call:INSERT INTO fred.CLIENTE (NOME) VALUES (?)
        bind => [fred]

tentei inserir um registro mas nao vai, da erro de not null, a JPA nao deveria fazer o select da sequence e preecher o campo “codigo”, igual o HIbernate??

Obs: To usando o TopLink

fredferrao

Eae galera, ninguem sabe alguma coisa, pra me dar uma luz??

A

Olá Fred,

Dê uma olhada nesses dois posts, acho que podem te ajudar…

http://stefan.arentz.nl/2006/05/20/glassfish-and-derby-and-postgresql/
http://stefan.arentz.nl/2006/05/20/glassfish-and-postgresql/

[]'s

Andre

fredferrao

ad-rocha:
Olá Fred,

Dê uma olhada nesses dois posts, acho que podem te ajudar…

http://stefan.arentz.nl/2006/05/20/glassfish-and-derby-and-postgresql/
http://stefan.arentz.nl/2006/05/20/glassfish-and-postgresql/

[]'s

Andre

Blz vou dar uma olhada!!

danieldestro

Também estou tendo problema com isto. Uso Oracle 10g XE, com Sequence.

Tentei de diversas maneiras usar a sequence como gerador do ID, mas não tá rolando. Estranhamento é jogado um valor “0” no meu ID (Integer) e dá o seguinte erro:

javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: minha.Class

Tentei das seguintes formas:

@Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="MINHA_SEQ_GEN") @SequenceGenerator(name="MINHA_SEQ_GEN", sequenceName="MINHA_SEQ", allocationSize=1) @Column(name="ID", nullable=false) private Integer id;

e assim:

@Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="MINHA_SEQ_GEN") @SequenceGenerator(name="MINHA_SEQ_GEN", sequenceName="MINHA_SEQ", allocationSize=1) private Integer id;

e assim:

@Id @GeneratedValue(strategy=GenerationType.SEQUENCE, sequenceName="MINHA_SEQ", allocationSize=1) private Integer id;

danieldestro

Caraca, mesmo usando HSQLDB, deixando o próprio Hibernate (com JPA) gerar o SCHEMA e configurando os IDs como @GeneratedValue(strategy=GenerationType.AUTO) ou mesmo como @GeneratedValue(strategy=GenerationType.SEQUENCE), nem assim funcionou e tive o mesmo problema.

urubatan

posta aqui as anotações do VO e o hibernate.hbm.xml pra darmos uma olhada …

Alexandre_Vilas_Boas

No Guia de Referencia, os exemplos anotam a classe com @SequenceGenerator e nao o atributo id, será esse o problema?

No entanto, encontro exemplos (das outras anotaçoes) na declaração do atributo ou no seu getter. :roll:

[]'s

danieldestro

Bom, to uando JPA em cima do Hibernate 3.2.1.

Fiz testes de atualização e os dados foram gravados corretamente, ao que parece. O problema é quando eu tento gravar um novo objeto no BD.

persistence.xml
<persistence>
	<persistence-unit name="xxx" transaction-type="RESOURCE_LOCAL">
		<properties>
			<property name="hibernate.show_sql" value="true" />
			<property name="hibernate.format_sql" value="false" />
 
			<property name="hibernate.connection.driver_class" value="oracle.jdbc.driver.OracleDriver" />
			<property name="hibernate.connection.url" value="jdbc:oracle:thin:@localhost:1521:XE" />
			<property name="hibernate.connection.username" value="xx" />
			<property name="hibernate.connection.password" value="xx" />
			<property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect" />
		</properties>
	</persistence-unit>
</persistence>
DAO
package xxx;

//imports

public class HibernateDAO implements DAO {
	private static final EntityManagerFactory emf;
	private static final EntityManager entityManager;
	
	static {
		emf = Persistence.createEntityManagerFactory("xxx");
		entityManager = emf.createEntityManager();
	}
	
	public HibernateDAO() {
	}

	public void remove(Object o) {
		try {
			entityManager.getTransaction().begin();
			entityManager.remove( o );
			entityManager.getTransaction().commit();
		} catch( RuntimeException e ) {
			entityManager.getTransaction().rollback();
			throw e;
		}
	}

	public void save(Object o) {
		try {
			entityManager.getTransaction().begin();
			entityManager.persist( o );
			entityManager.getTransaction().commit();
		} catch( RuntimeException e ) {
			entityManager.getTransaction().rollback();
			throw e;
		}
	}
}
Entidade.java
package yyy;

//imports

@Entity
public class Entidade implements Serializable {
	private static final long serialVersionUID = 3746705610857081940L;
	
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Integer id;
	private String nome;
	@Column(name="NOME_COMUM")
	private String nomeComum;
	
	public Entidade () {
	}

        // gets e sets
}

Mesmo usando HSQLDB (ele criando as tabelas) e @GeneratedValue(strategy=GenerationType.SEQUENCE), não tá rolando.

danieldestro

Putz… acabei de descobrir que o problema não era o JPA/Hibernate.
Como eu uso Apache Commons Bean Utils para jogar os valores da tela para o objeto de dados, quando é null ele joga “0” no campo Integer, que no caso é o ID. Que merda! Não deveria jogar “0”.

Alexandre_Vilas_Boas

humm… copyProperties neh, parei de usar por conta dos campos date, como vc faz com eles?

danieldestro

Na verdade eu to usando o populate() e ainda não tratei datas.

A

eu estou com um problema com sequence:

no banco minha sequence se chama “seq_tbl_equipamento”. Porém, quando tento inserir um registro é gerada uma exceçção:

org.postgresql.util.PSQLException: ERRO: relação “tbl_equipamento_int_idaequipamento_seq” não existe

Quando altero o nome da sequence no banco para o mesmo nome da sequence dessa exceção (tbl_equipamento_int_idaequipamento_seq), aí sim eu consigo inserir meu objeto. Mas eu queria saber o porquê dessa exceção, o porquê de não aceitar a sequence do banco e exigir a que é gerada na exceção.

parte do código da sequence:

@Id

@GeneratedValue(strategy = GenerationType.SEQUENCE, generator=EquipamentoSeq)

@SequenceGenerator(name=EquipamentoSeq, sequenceName=seq_tbl_equipamento, allocationSize=1)

@Column(name = int_idaequipamento, nullable = false)

private Integer intIdaequipamento;

Obrigado pela atenção.

Akila

Cara, vc pode usar o copyproperty, e para resolver esse problema de atribuir 0 no campo, vc pode registrar uns conversores para o seu tipo. Assim, vc faz o converso para o Tipo Integer que ao receber string vazia, “”, ele não coloque 0 e sim null.

C

Estava com o mesmo problema, consegui solucionar incluido a anotação no cabeçalho da classe:
@SequenceGenerator(name=“SQ_ENTIDADE”,sequenceName=“SQ_ENTIDADE”)

Depois da tag @Table

clakrall

Na minha classe conseguir configurar corretamento com a anotação:

@Entity

@Table(name=agentes_credito_tipos)

@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)

public class AgenteCreditoTipo implements Serializable {

@Id

@SequenceGenerator( name = AGENTE_CREDITO_TIPO_ID, sequenceName = agentes_credito_tipos_seq, allocationSize = 1 )

@GeneratedValue( strategy = GenerationType.SEQUENCE, generator = AGENTE_CREDITO_TIPO_ID )

@Column( name = ID, nullable = false )

private Integer id;



}
newbare

Tive esse problema com uma aplicação gerada pelo Seam, quando as telas foram geradas o campo ID das tabelas de banco também foi criado, logo ele submetia 0(zero) na renderização quando deveria passar null, ou seja, retire todos os campos gerados para o ID, utilize as anotações para gerar a sequenci, no meu caso utilizei o postgres então ficou assim:

@Entity

@SequenceGenerator(name= seq_cod_raca, allocationSize = 1, sequenceName = public.seq_cod_raca)

@Table(name = raca)

public class Raca implements java.io.Serializable {}
@Id

@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = seq_cod_raca)

@Column(name = codraca, unique = true, nullable = false)

public int getCodraca() {

return this.codraca;

}

versão do Seam: 2.1.2
Jboss tools: 3.0
jboss Server 5.0.1 GA
tem um artigo massa com todos os passos:
http://www.devmedia.com.br/post-8660-Introducao-ao-Jboss-Seam-Parte-8.html

newbare

Tive esse problema com uma aplicação gerada pelo Seam, quando as telas foram geradas o campo ID das tabelas de banco também foi criado, logo ele submetia 0(zero) na renderização quando deveria passar null, ou seja, retire todos os campos gerados para o ID, utilize as anotações para gerar a sequenci, no meu caso utilizei o postgres então ficou assim:

@Entity

@SequenceGenerator(name= seq_cod_raca, allocationSize = 1, sequenceName = public.seq_cod_raca)

@Table(name = raca)

public class Raca implements java.io.Serializable {}
@Id

@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = seq_cod_raca)

@Column(name = codraca, unique = true, nullable = false)

public int getCodraca() {

return this.codraca;

}

versão do Seam: 2.1.2
Jboss tools: 3.0
jboss Server 5.0.1 GA
tem um artigo massa com todos os passos:
http://www.devmedia.com.br/post-8660-Introducao-ao-Jboss-Seam-Parte-8.html

X

ressuscitando…
Não tem mt haver com o topico, amis eu não quero criar outro…

Tenho duvina nessa a notação:

@GeneratedValue(strategy = GenerationType.IDENTITY)

A duvida é para sabe para serve o (strategy = GenerationType.IDENTITY)…?

Criado 6 de novembro de 2006
Ultima resposta 12 de dez. de 2011
Respostas 22
Participantes 12