JPA - Merge fazendo um select ao invés de um update

7 respostas
wescleyfcosta

Opa,

Estou fazendo uma atualização em uma entidade cuja a implementação do DAO é a única diferente das demais do meu sistema, o merge dela não grava um log, para fazer isso eu eu estendi e reescrevi o método que salva (onde está o merge), acontece uma coisa muito estranha nessa classe, agora, sempre que passo na linha do merge, aparece um select no log do console e o update não é feito. Se eu tiro a parte que reescrevi e deixo o método mais genérico, ele faz o update normalmente… Alguém sabe porque da essa locura?

Quando passo nessa linha

Aparece no console

select entidadeco0_.id as id0_0_, entidadeco0_.id_entidade as id2_0_0_, entidadeco0_.nome_entidade as nome3_0_0_, entidadeco0_.situacao_integracao as situacao4_0_0_ from tb_entidade_controle_fila entidadeco0_ where entidadeco0_.id=?

7 Respostas

maior_abandonado

wescleyfcosta:
Opa,

Estou fazendo uma atualização em uma entidade cuja a implementação do DAO é a única diferente das demais do meu sistema, o merge dela não grava um log, para fazer isso eu eu estendi e reescrevi o método que salva (onde está o merge), acontece uma coisa muito estranha nessa classe, agora, sempre que passo na linha do merge, aparece um select no log do console e o update não é feito. Se eu tiro a parte que reescrevi e deixo o método mais genérico, ele faz o update normalmente… Alguém sabe porque da essa locura?

Quando passo nessa linha

Aparece no console

select entidadeco0_.id as id0_0_, entidadeco0_.id_entidade as id2_0_0_, entidadeco0_.nome_entidade as nome3_0_0_, entidadeco0_.situacao_integracao as situacao4_0_0_ from tb_entidade_controle_fila entidadeco0_ where entidadeco0_.id=?

se é feito um select e não um update então desconfio que o seu objeto não era gerenciado pelo hibernate, seu merge está retornando outro objeto que por sua vez seja identico porém seja gerenciado.

Um detalhe é que se bem me lembro, o hibernate só daria inserts por exemplo quando passa pela linha que chama o commit do seu objeto transaction, não tenho certeza se isso vale para o merge também.

Faz um experimento ai, troque

por

o retorno do merge seria gerenciado então teoricamente se já é gerenciado acho que ele daria o update.

wescleyfcosta

maior_abandonado:
wescleyfcosta:
Opa,

Estou fazendo uma atualização em uma entidade cuja a implementação do DAO é a única diferente das demais do meu sistema, o merge dela não grava um log, para fazer isso eu eu estendi e reescrevi o método que salva (onde está o merge), acontece uma coisa muito estranha nessa classe, agora, sempre que passo na linha do merge, aparece um select no log do console e o update não é feito. Se eu tiro a parte que reescrevi e deixo o método mais genérico, ele faz o update normalmente… Alguém sabe porque da essa locura?

Quando passo nessa linha

Aparece no console

select entidadeco0_.id as id0_0_, entidadeco0_.id_entidade as id2_0_0_, entidadeco0_.nome_entidade as nome3_0_0_, entidadeco0_.situacao_integracao as situacao4_0_0_ from tb_entidade_controle_fila entidadeco0_ where entidadeco0_.id=?

se é feito um select e não um update então desconfio que o seu objeto não era gerenciado pelo hibernate, seu merge está retornando outro objeto que por sua vez seja identico porém seja gerenciado.

Um detalhe é que se bem me lembro, o hibernate só daria inserts por exemplo quando passa pela linha que chama o commit do seu objeto transaction, não tenho certeza se isso vale para o merge também.

Faz um experimento ai, troque

por

o retorno do merge seria gerenciado então teoricamente se já é gerenciado acho que ele daria o update.

blz, vou dar uma testada… mas eu fiz um find na entidade antes de chamar o esse método, e na teoria ele ficaria gerenciado, e como eu disse só da essa zica quando estendo a classe

danilo.akamine

se você fez um find() na entidade, ela já está gerenciável pelo Hibernate, logo não precisaria chamar mais nenhum método do seu Entity Manager.
simples chamadas nos setters já deveriam atualizar a entidade ao commitar.

wescleyfcosta

danilowz:
se você fez um find() na entidade, ela já está gerenciável pelo Hibernate, logo não precisaria chamar mais nenhum método do seu Entity Manager.
simples chamadas nos setters já deveriam atualizar a entidade ao commitar.

Isso é verdade, mas está tão esquisito que nem isso deu certo, devo ter feito alguma zica no código que tá afetando essa parte, de qualquer forma eu mudei a maneira que estava fazendo para continuar…

danilo.akamine

eu ainda acho que esse comportamento do merge() é normal, não vai ser executado um UPDATE logo de cara, apenas qndo commitar.
por ex:

public void salvar() {
	Entidade entidadeManaged = em.merge(entidadeDetached);	// causa um SELECT para sincronizar sua entidade com o banco
	entidadeManaged.setNome("blablabla");
	em.getTransaction().commit();	// causa um UPDATE para atualizar o nome
}
wescleyfcosta

danilowz:
eu ainda acho que esse comportamento do merge() é normal, não vai ser executado um UPDATE logo de cara, apenas qndo commitar.
por ex:

public void salvar() { Entidade entidadeManaged = em.merge(entidadeDetached); // causa um SELECT para sincronizar sua entidade com o banco entidadeManaged.setNome("blablabla"); em.getTransaction().commit(); // causa um UPDATE para atualizar o nome }

É que estou usando o esquema de transação do Spring, então, se entendi bem, ele vai fazer o commit sempre que um método transacional acabar… posso tentar com um flush? vou tentar as duas maneiras ainda hj, ai reporto o que deu… muito obrigado

danilo.akamine

exato, repare que assim que acabar a transação, as queries DML (update, insert, delete) serão executadas.
pode testar com o flush() tbm se quiser forçar o update antes de acabar a transação.

Criado 21 de março de 2012
Ultima resposta 22 de mar. de 2012
Respostas 7
Participantes 3