Detached objects, diferenças no Hibernate e Eclipselink/Toplink

3 respostas
G

Tenho um código que funciona bem no JPA usando o Hibernate como provider.

Customer customer = em.find(10, Customer.class);

// aqui eu associo uma tarifa ao cliente
customer.setRate(new Rate(1));

No caso eu mando salvar isso no Hibernate e funciona bem. O Hibernate vê que eu quero apenas associar uma tarifa no objeto customer e no final o comando SQL gerado é:

update customer set rate_id = 1

Porém rodando no Eclipselink/Toplink retorna erro, pois ele tenta incluir o objeto Rate ao invés de apenas atualizar o customer.

ERROR: null value in column "value" violates not-null constraint
Call: INSERT INTO RATE (ID, VALUE0, DESCRIPTION, VALUE, VALUE1) VALUES (?, ?, ?, ?, ?)
	bind => [1, null, null, null, null]

No mapeamento das entidades não há cascade, sendo assim ele não deveria fazer nada. Como o Eclipselink trata esses objetos? Eu devo fazer alguma coisa antes de salva-los?

3 Respostas

L
garcia-jj:
Tenho um código que funciona bem no JPA usando o Hibernate como provider.
Customer customer = em.find(10, Customer.class);

// aqui eu associo uma tarifa ao cliente
customer.setRate(new Rate(1));

No caso eu mando salvar isso no Hibernate e funciona bem. O Hibernate vê que eu quero apenas associar uma tarifa no objeto customer e no final o comando SQL gerado é:

update customer set rate_id = 1

Porém rodando no Eclipselink/Toplink retorna erro, pois ele tenta incluir o objeto Rate ao invés de apenas atualizar o customer.

ERROR: null value in column "value" violates not-null constraint
Call: INSERT INTO RATE (ID, VALUE0, DESCRIPTION, VALUE, VALUE1) VALUES (?, ?, ?, ?, ?)
	bind => [1, null, null, null, null]

No mapeamento das entidades não há cascade, sendo assim ele não deveria fazer nada. Como o Eclipselink trata esses objetos? Eu devo fazer alguma coisa antes de salva-los?

Sinceramente, não sei porque há essa diferença. Na minha opinião, o correto (quando não há cascade) seria lançar uma exceção, dizendo que o objeto é transiente.

Eu nunca vou por essa opção. Prefiro ter uma referência attached do objeto a ser criado o relacionamento, assim:

Customer customer = em.find(10, Customer.class);
Rate rate = em.find(1, Rate.class);
customer.setRate(rate);
root_

Estou me debatendo com este mesmo tipo de problema… estou trabalhando em um sistema utilizando Hibernate e outro em paralelo utilizando EclipseLink.
O sistema possui vários banco de dados stadalone, podendo o usuário escolher o banco que ele quer trabalhar.

O EclipseLink tenta realizar insert no lugar de um simples update… já pesquisei até e ainda não encontrei alguma solução para meu problema em questão…
O engraçado é que com Hibernate acontece o update normalmente.
Leonardo3001 você já conseguiu resolver este problema?
Como resolve-lo, ainda mais quando se trabalhar com conceito de OpenSession in View?

G

Eu notei que o Eclipselink tem o mesmo comportamento do hibernate quando você tem classes simples. No relacionamento como o que eu coloquei lá encima ele funciona corretamente sem problemas, assim como no Hibernate.

Porém quando na minha classe possui alguma classe embedded, o Eclipselink tenta fazer o insert.

Eu acabei deixando de lado isso porque aquele sistema era feito para rodar com JPA usando o Hibernate como provider. Embora eu queria mantê-lo compliance com a API padrão, achei que iriamos perder muito tempo para resolver, e deixei de lado.

Criado 1 de julho de 2010
Ultima resposta 25 de abr. de 2011
Respostas 3
Participantes 3