Hibernate Generator e Trigger

EU tenho uma tabela que já tem um trigger e uma sequence pra popular o IDO após o insert.

Pelo manual do hibernate, devo usar o generator select (“retrieves a primary key assigned by a database trigger by selecting the row by some unique key and retrieving the primary key value”).

Meu arquivo de configuração ficou:

<hibernate-mapping>
<class name=“gov.tresc.admsist.model.Usuario” table=“USUARIO”
schema=“ADMSIST”>
<id name=“id” column=“IDO_USUARIO” type=“long”>
<generator class=“select”/>
</id>
<property name=“nome” column=“NOME_USUARIO” type=“string” length=“70”
not-null=“true”/>
<property name=“login” column=“LOGIN” type=“string” length=“70”
not-null=“true”/>
<property name=“email” column=“E_MAIL” type=“string” length=“70”
not-null=“true”/>
</class>
</hibernate-mapping>

mas da o seguinte erro no momento de salvar (dódigo abaixo):

codigo: user = (Usuario) ServiceLocator.currentSession().save(user);

erro:

Hibernate: insert into ADMSIST.USUARIO (NOME_USUARIO, LOGIN, E_MAIL) values (?, ?, ?)
org.hibernate.MappingException: unknown property: null
at org.hibernate.persister.entity.AbstractPropertyMapping.getColumnNames(AbstractPropertyMapping.java:54)
at org.hibernate.persister.entity.BasicEntityPersister.getPropertyColumnNames(BasicEntityPersister.java:1112)
at org.hibernate.persister.entity.BasicEntityPersister.getSelectByUniqueKeyString(BasicEntityPersister.java:1769)
at org.hibernate.id.SelectGenerator.getSQL(SelectGenerator.java:35)
at org.hibernate.id.AbstractPostInsertGenerator.getGenerated(AbstractPostInsertGenerator.java:34)
at org.hibernate.persister.entity.BasicEntityPersister.insert(BasicEntityPersister.java:1755)
at org.hibernate.persister.entity.BasicEntityPersister.insert(BasicEntityPersister.java:2149)
at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:34)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:239)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:238)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:158)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:104)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:184)
at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:33)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:173)
at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:27)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:69)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:429)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:424) at gov.tresc.admsist.dao.DAOAdmSist.criaUsuario(DAOAdmSist.java:135) at gov.tresc.admsist.AdmSistFacade.criaUsuario(AdmSistFacade.java:53) at gov.tresc.admsist.struts.UsuariosCRUDAction.criarFinish(UsuariosCRUDAction.java:40)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585) at org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:280)

Pelo menos na versão do Hibernate que estou usando não existe generator do tipo “select”.

Olhe novamente a documentação, acho que o que você precisa é o sequence.

bem, na versão 3.0RC1 tem :slight_smile: página 36, primeiro item.

Eu já tenho um trigger que popula o id de cada registro. Não preciso que o hibernate o faça.

Este erro parece estar relacionado com alguma outra coisa :frowning:

obrigado de qualquer forma, se alguem puder ajduar, agradeço.

Emerson

Ainda não coloquei as mãos nesta belezinha hehe
inveja

Bem, está apontando para o dtd da versão correta? chutando
Já tentou com outro generator só para testar?

Já vi que foi um menino inteligente e postou no fórum do Hibernate :smiley: se responderem por lá, por favor não esqueça de postar a solução aqui :thumbup:

Realmente teve algumas mudanças, mas nada demais, pelo menos não utilizei muitas features avançadas. mudou alguns nomes pacotes e a sintaxe na utilização de sessions.

Em relação ao meu problema, me responderam na lista do hibernate. É que no hibernate reference, não é explicado que é necessário um parâmetro contendo uma chave única para o hibernate poder retornar a chave que foi gerada pelo trigger.

Trecho do manual:

http://www.hibernate.org/hib_docs/v3/reference/en/html/mapping.html#mapping-declaration-id-select

In the above example, there is a unique valued property named socialSecurityNumber defined by the class, as a natural key, and a surrogate key named person_id whose value is generated by a trigger.

Enfim, não funcionou mesmo assim, postei novamente no forum do hibernate.

Troquei pra sequence usando o generator sequence, e finalmente funcionou, porém gastando duas sequences por objeto, pois o trigger pega um valor e o hibernate pega o próximo. O que dá pra fazer também é alterar a sequence para não atualizar o id do registro sendo inserido caso este não seja nulo.
novo post forum hibernate:
http://forum.hibernate.org/viewtopic.php?p=2233776&sid=d16e63fe4c8b1375caef4b26a9bcfd4a#2233776

flw pessoal
Emerson Cargnin
floripa

Hum, pelo que entendi o lance do generator ‘select’ é apenas para dados legados, pois o funcionamento dele é uma caca. Tem certeza que essa é a melhor opção?

De qualquer maneira, já que a exception lançada é

java.lang.ClassCastException: java.lang.String

Tente mudar a declaração

 &lt;param name="key"&gt;login&lt;/param&gt;

para algum outro parâmetro da classe do tipo Long.

Postei lá no fórum do hibernate para dar uma força. O pessoal que manja por lá é f*.

O problema é que tem outras aplicações usando direto o banco, então não tenho como mudar… o que posso fazer é usar outro valor da sequence e deixar um vago mesmo…

O único parâmetro que tem long é o próprio ID, que é gerado pelo trigger…

vlw
Emerson

Droga não poder mexer no banco :expressionless:

Bem, você percebeu que a merda toda acontece aqui

Hibernate: select IDO_USUARIO from ADMSIST.USUARIO where LOGIN =?

Pois o Hibernate está transformando o valor retornado em String e não Long, e quando tenta setar o person_id com este valor a coisa explode.

Que tal fazer uma gambiarrinha de teste?
Mude o método setId para o seguinte

public void setId( String id ) { this.id = Long.valueOf( id ); }

Lembre: apenas para teste hehe

Acho que o hibernate teria que setar no setId com o ID (long) e não com a string login que é apenas para ele poder localizar o objeto que acabou de inserir. Talvez seja algum bug do generator ou necessite ter algum atributo único com o mesmo tipo que a chave, estranho não? Deixa quieto, se não responderem lá, vou usar o generator sequence mesmo :slight_smile:
vlw pela força :slight_smile:
[]s
Emerson

[quote=LIPE]Droga não poder mexer no banco :expressionless:

Bem, você percebeu que a merda toda acontece aqui

Hibernate: select IDO_USUARIO from ADMSIST.USUARIO where LOGIN =?

Pois o Hibernate está transformando o valor retornado em String e não Long, e quando tenta setar o person_id com este valor a coisa explode.

Que tal fazer uma gambiarrinha de teste?
Mude o método setId para o seguinte

public void setId( String id ) { this.id = Long.valueOf( id ); }

Lembre: apenas para teste hehe[/quote]