[RESOLVIDO] PostgreSQL + Hibernate

11 respostas
bglbruno

Olá, boa tarde pessoal!

Estou tendo problemas quando tento gravar algum bean no banco, o hibernate reclama e exibe a seguinte mensagem

select nextval ('hibernate_sequence')
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing

É a primeira vez que trabalho com postgreSQL. No MySQL gravava normal com as mesmas configs.
O que devo alterar?
Acredito que seja algo com o equivalente ao auto_increment do MySQL
Alguma dica galera?

Desde já agradeço!

11 Respostas

E

Como está mapeado??

Em xml é feito passando o nome da sequence, ex:

<id column='"compartilhaProcessoId"' name="compartilhaProcessoId" type="long">
  		<generator class="native">
  			<param name="sequence">"mDgtCompartilhaProcesso_compartilhaProcessoId_seq"</param>
  		</generator>
  	</id>

dá pra fazer por annotations tbem, esse eu fiz utilizando jpa

@Id
@SequenceGenerator(name="H2OCALCULO__CALCULAID__GENERATOR", sequenceName="\"h2oCalculo_calculaId_seq\"", allocationSize=1)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="H2OCALCULO__CALCULAID__GENERATOR")
@Column(name="\"calculoId\"")
private long calculoId;

abraco,

Evandro

bglbruno

Então cara, eu mapeio com annotations, e está assim

@Entity
public class Equipamento {

	@Id
	@GeneratedValue	
	private long idEquipamento;

	...
}

Não estou usando JPA, to usando hibernate mesmo. Muda alguma coisa?
Para cada tabela vou ter que criar uma sequence?

E

Cara, na verdade, da maneira como eu utilizo aqui, o sequence já é gerado automaticamente, pego somente o nome lá no pgadmin.

Quando crio a tabela, ja coloco o campo chave como serial, ou bigserial, e automaticamente o postgres já cria a sequence padrão.

abs,

Evandro

narciso.benigno

Pode ser basicamente 2 coisas:

Você está tentando salvar um objeto que tem outro objeto, e este outro objeto não está salvo e não há a configuração de cascata para este outro objeto.

Ou você está tentando dar um update, em um objeto sem o id, o que não me parece, já que o dialeto do PostgresSQL pelo log que você mandou ele executou o select da sequence.

Abraço,

bglbruno

Evandro_Contato:
Cara, na verdade, da maneira como eu utilizo aqui, o sequence já é gerado automaticamente, pego somente o nome lá no pgadmin.

Quando crio a tabela, ja coloco o campo chave como serial, ou bigserial, e automaticamente o postgres já cria a sequence padrão.

abs,

Evandro

Na classe, como faço para falar que o indice é do tipo Serial ?

Narciso, é isso ai, essa minha classe Equipamento tem um relacionamento @OneToOne

@OneToOne(fetch=FetchType.LAZY, cascade=CascadeType.REMOVE)
	@JoinColumn(name = "idInfo")
	private EquipamentoInfoTecnica info;

Devo fazer mais alguma configuração/mapeamento?

R

bglbruno:
Então cara, eu mapeio com annotations, e está assim

@Entity
public class Equipamento {

	@Id
	@GeneratedValue	
	private long idEquipamento;

	...
}

Não estou usando JPA, to usando hibernate mesmo. Muda alguma coisa?
Para cada tabela vou ter que criar uma sequence?

Bruno,
geralmente eu faço assim:

  • a coluna que vai ser PK fica com tipo ‘serial’ (o Postgres já cria a sequence automaticamente)

No JPA indico a sequence:

@SequenceGenerator(name = "cli", sequenceName = "tb_cliente_id_seq",allocationSize=1)  
	@Id
	@Column
	@GeneratedValue(strategy=GenerationType.SEQUENCE, generator = "cli")  
	Long id;
bglbruno

raf4ever:

Bruno,
geralmente eu faço assim:

  • a coluna que vai ser PK fica com tipo ‘serial’ (o Postgres já cria a sequence automaticamente)

No JPA indico a sequence:

@SequenceGenerator(name = "cli", sequenceName = "tb_cliente_id_seq",allocationSize=1) @Id @Column @GeneratedValue(strategy=GenerationType.SEQUENCE, generator = "cli") Long id;

Existe algum padrão que o Pg utiliza para nomear essas sequences?

Mas cara, eu não to usando JPA, só hibernate. Muda alguma coisa?

R

Sim,fica ‘nomeDaTabela_id_seq’

Vc nunca usa “só” JPA pois o mesmo é apenas a especificação,sempre se usa uma implementação por baixo,Hibernate na maioria dos casos.

Deu pra entender? :wink:

narciso.benigno

bglbruno:
Evandro_Contato:
Cara, na verdade, da maneira como eu utilizo aqui, o sequence já é gerado automaticamente, pego somente o nome lá no pgadmin.

Quando crio a tabela, ja coloco o campo chave como serial, ou bigserial, e automaticamente o postgres já cria a sequence padrão.

abs,

Evandro

Na classe, como faço para falar que o indice é do tipo Serial ?

Narciso, é isso ai, essa minha classe Equipamento tem um relacionamento @OneToOne

@OneToOne(fetch=FetchType.LAZY, cascade=CascadeType.REMOVE)
	@JoinColumn(name = "idInfo")
	private EquipamentoInfoTecnica info;

Devo fazer mais alguma configuração/mapeamento?

O cascade está apenas para o Remove, se ela não for salva previamente, ele vai dar o erro que aparece, para fazer o insert você deve colocar o cascade CREATE

E

Na classe ela fica como int,

Na criacao da tabela no pgadmin vc coloca que o campo é do tipo serial para int na classe, ou na bigserial, sendo dai long na classe,

Qdo vc cria a tabela, ele identifica que vc colocou o tipo do campo como serial, entao cria o campo do tipo int na tabela e automaticamente cria a sequence, faz um teste ai no seu pgadmin para vc ver o comportamento :wink:

abs,

Evandro

bglbruno

Valeu pessoal! Consegui resolver com a dica do raf4ever e do narciso.benigno, muito obrigado galera!
Evandro, muito obrigado também, me ajudou a encontrar o caminho :slight_smile:

Valeu pessoal, forte abraço!

Criado 25 de outubro de 2011
Ultima resposta 25 de out. de 2011
Respostas 11
Participantes 4