Que bagunça...
AUTO_INCREMENT
é a sequência oculta do MySQL. O problema radical é que MySQL
não pode inserir e retornar o PK ao mesmo tempo, mas o Hibernate precisa disso enquanto INSERT
em uma nova Entidade. Os problemas que você encontra:
- Se o Hibernate salvar uma nova Entity, ele tentará definir o id por imersão para o novo EntityBean. Portanto, o hibernate deve ler qual ID o banco de dados usará antes que o hibernate salve a nova tupla na tabela.
- Se você tiver vários servidores que acessam o banco de dados, você deve deixar a fábrica de sessão do hibernate decidir usar a sequência embutida (AUTO-INCREMENT) ou deixar o hibernate decidir (
GenerationType.AUTO
/GenerationType.IDENTITY
) quão grande é o intervalo aberto de PKs reservados (Job of a DB-Architect). (Temos cerca de 20 servidores para um banco de dados, então em uma tabela bem usada usamos uma distância PK de +100). Se apenas um servidor tiver acesso ao banco de dadosGenerationType.TABLE
deve estar correto.
O Hibernate deve calcular o próximo id usando
max(*)+1
mas:- E se duas solicitações solicitarem
max(*)+1
ao mesmo tempo/com o mesmo resultado? Direita:A última tentativa deinsert
vai falhar.
Então você precisa ter uma Tabela
LAST_IDS
no banco de dados que armazena as últimas Table-PK's. Se você quiser adicionar um, você deve seguir estas etapas:- Iniciar transação otimizada para leitura.
- SELECT MAX(address_id) FROM LAST_IDS
- armazene o máximo em uma variável java, ou seja:$OldID.
- $NewID =$OldID + 1. (+100 no bloqueio pessimista)
- UPDATE LAST_IDS SET address_id=
$newID
WHERE address_id=$oldID
? - confirme a transação otimizada para leitura.
- se a confirmação foi bem-sucedida, armazene
$newID
parasetID()
no HibernateBean que você deseja salvar. - Finalmente, deixe o Hibernate chamar a inserção.
Esta é a única maneira que eu conheço.
BTW:Hibernate-Entitys só deve usar herança se o banco de dados suportar herança entre tabelas como
PostgreSQL
ou Oracle
.