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”).
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)
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.
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
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
<param name="key">login</param>
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…
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
vlw pela força
[]s
Emerson
[quote=LIPE]Droga não poder mexer no banco
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 );
}