Ao criar o registro via Browser e mandar salvar, o hibernate está gerando o seguinte erro:
Olhando o erro, é lógico que o ID está nulo, eu quero inserir um registro no banco de dados, numa tabela com primary key auto_increment. Ou seja, quero que o banco retorne o valor, por isso ele entra como nulo.
Fora esse campo, a tabela possui vários outros campos e um deles é unique, tanto no banco como no mapeamento do hibernate.
O método checkID() onde está lançando a exception:
publicvoidcheckId(Objectobject,EntityPersisterpersister,Serializableid,EntityModeentityMode)throwsHibernateException{if(id!=null&&idinstanceofDelayedPostInsertIdentifier){// this is a situation where the entity id is assigned by a post-insert generator// and was saved outside the transaction forcing it to be delayedreturn;}if(persister.canExtractIdOutOfEntity()){Serializableoid=persister.getIdentifier(object,entityMode);if(id==null){thrownewAssertionFailure("null id in "+persister.getEntityName()+" entry (don't flush the Session after an exception occurs)");}if(!persister.getIdentifierType().isEqual(id,oid,entityMode)){thrownewHibernateException("identifier of an instance of "+persister.getEntityName()+" was altered from "+id+" to "+oid);}}}
Caso isso ajude.
V
victorwss
Guilherme Gomes:
O método checkID() onde está lançando a exception:
publicvoidcheckId(Objectobject,EntityPersisterpersister,Serializableid,EntityModeentityMode)throwsHibernateException{if(id!=null&&idinstanceofDelayedPostInsertIdentifier){// this is a situation where the entity id is assigned by a post-insert generator// and was saved outside the transaction forcing it to be delayedreturn;}if(persister.canExtractIdOutOfEntity()){Serializableoid=persister.getIdentifier(object,entityMode);if(id==null){thrownewAssertionFailure("null id in "+persister.getEntityName()+" entry (don't flush the Session after an exception occurs)");}if(!persister.getIdentifierType().isEqual(id,oid,entityMode)){thrownewHibernateException("identifier of an instance of "+persister.getEntityName()+" was altered from "+id+" to "+oid);}}}
Caso isso ajude.
Bem, se é bug ou não eu não sei, mas é no mínimo uma aplicação incorreta do conceito de assertivas. Um método público não deve validar parâmetros com assertivas.
R
romuloff
victorwss:
Guilherme Gomes:
O método checkID() onde está lançando a exception:
Bem, se é bug ou não eu não sei, mas é no mínimo uma aplicação incorreta do conceito de assertivas. Um método público não deve validar parâmetros com assertivas.
Vitor. esse código é do hibernate … :idea:
org.hibernate.event.def.DefaultFlushEntityEventListener
R
rick_gallagher
Eu to passando pelo mesmo problema do Guilherme…
Se alguem souber, por favor da um help! :?
D
daniel.joppi
como resolveram?
V
vinnysoft
Boa noite!
Eu já passei por essa situação. Comigo aconteceu logo após uma ConstraintViolationException do hibernate, então não conseguia fazer mais nada durante aquela sessão. Dei uma lida em alguns forums (inclusive aqui: http://www.guj.com.br/java/100669-problema-hibernate-entry-dont-flush-the-session-after-an-exception-occurs) , e disseram que o hibernate da rollback na transação e invalida as demais tentativas daquela sessão. Isso é até, de certa forma, o correto a se fazer, pois vc não tem certeza do estado do banco de dados após uma exceção, então acredito que o Hibernate proceda assim para que possa ser verificada a consistência do banco.
Como eu sei que era intencional meu erro de ConstraintViolationException, corrigi este problema simplesmente fechando e abrindo outra sessão:
catch (ConstraintViolationException e)
{
FacesContext.getCurrentInstance().addMessage("Mensagem", new FacesMessage(FacesMessage.SEVERITY_WARN,
"Este atributo já está cadastrado!", ""));
ss.close();
ss = factory.openSession();
}
Mas como disse, deve ter cuidado com essa opção… no meu caso resolveu, mas foi por minha conta e risco!
Até +!
D
daniel.joppi
mas ai você abre a nova sessão e re-faz a transação?
V
vinnysoft
Boa noite!
Neste caso nao, pois esse erro de Constraint é se já existe um objeto com os mesmos dados (atributos configurados como constraint) do que o objeto na view, então simplesmente exibo uma mensagem ao usuário que o objeto já existe, que ele não pode inseri-lo novamente.
Então não há necessidade de retentar a mesma transação, mas sim que ele altere os dados da view e tente novamente.
Até +!
D
dutrajardim
Estou montando uma aplicação e encontrei o mesmo problema. Após muita pesquisa consegui resolver.
O problema é que de acordo com a mensagem de erro informado pelo Hibernate da a entender que o problema é no ID, “Olhando o erro, é lógico que o ID está nulo”. Porem no meu caso o erro não era esse.
Consegui resolver o problema após rever os arquivos xml de mapeamento (.hbm). Especificações de tipagem, limitações(Ex. length), e descrição do relacionamento tem que estar de acordo com o bd, caso contrario o hibernate retorna essa mensagem.
Espero ter ajudado!
R
RenatoBM
Também passei por isso, mas o meu caso era justamente o que o caro colega, DutraJardim, comentou (valeu cara!): Era uma inconsistência entre o Hibernate e o BD. Esses tipos de problema em que a mensagem nada tem a ver com o que realmente acontece é que nos deixa loucos…
J
jondavy
pessoal tbem estou passando por isso, como resolveram?
parte do meu codigo…
minha classe cliente
@Entity@Table(name="cliente")publicclassClienteimplementsjava.io.Serializable{@Id@GeneratedValueprivateIntegercodigo;@Column(name="nome",unique=true)privateStringnome;@Column(name="cpf",unique=true)privateStringcpf;//outros atributos construtores e getters e setters
meu clienteDAO
public class ClienteDAO<Cliente> {
private Session session;
public void save(Cliente cliente) throws HibernateException {
try {
session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
session.persist(cliente);
} finally {
session.getTransaction().commit();
}
}
a exception gerada
J
jondavy
realmente é um erro estranho a solucao que tive foi remover o atributo da anotação unique dos campos e do banco, depois disso o erro nao aconteceu mais,
temporariamente vou ter q fazer uma consulta no aplicativo para nao haver nomes & cpf duplicados no banco de dados antes de inserir o registro apesar de nao ser a melhor pratica, pois como o vinigodoy disse sobrecarrega um pouco o banco com consultas