Todos nós conhecemos o comportamento padrão do Hibernate ao usar @SequenceGenerator
- aumenta a sequência real do banco de dados em um , multiplica este valor por 50 ( allocationSize
valor padrão ) - e então usa este valor como ID de entidade.
Este é um comportamento incorreto e conflita com a especificação que diz:
alocaçãoSize - (opcional) a quantidade a ser incrementada ao alocar números de sequência da sequência.
Para ser claro: não me preocupo com as lacunas entre os IDs gerados.
Preocupo-me com IDs que não são consistentes com a sequência de banco de dados subjacente. Por exemplo: qualquer outro aplicativo (que usa JDBC simples) pode querer inserir novas linhas sob os IDs obtidos na sequência - mas todos esses valores já podem ser usados pelo Hibernate! Loucura.
Alguém conhece alguma solução para este problema (sem configurar allocationSize=1
e assim degradar o desempenho)?
EDIT:
Para tornar as coisas claras. Se o último registro inserido tinha ID = 1
, então o HB usa valores 51, 52, 53...
para suas novas entidades MAS ao mesmo tempo: o valor da sequência no banco de dados será definido como 2
. O que pode facilmente levar a erros quando outros aplicativos estiverem usando essa sequência.
Por outro lado: a especificação diz (no meu entendimento) que a sequência do banco de dados deveria ter sido definida para 51
e, entretanto, o HB deve usar valores do intervalo 2, 3 ... 50
ATUALIZAÇÃO:
Como Steve Ebersole mencionou abaixo: o comportamento descrito por mim (e também o mais intuitivo para muitos) pode ser habilitado por configuração hibernate.id.new_generator_mappings=true
.
Obrigado a todos vocês.
ATUALIZAÇÃO 2:
Para futuros leitores, abaixo você pode encontrar um exemplo prático.
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USERS_SEQ")
@SequenceGenerator(name = "USERS_SEQ", sequenceName = "SEQUENCE_USERS")
private Long id;
}
persistence.xml
<persistence-unit name="testPU">
<properties>
<property name="hibernate.id.new_generator_mappings" value="true" />
</properties>
</persistence-unit>
save
precisa consultar o banco de dados para o próximo valor da sequência.
SequenceGenerator
Hibernate irá consultar o banco de dados somente quando a quantidade de IDs especificados por allocationsize
acabar. Se você configurou allocationSize = 1
, esse é o motivo pelo qual o Hibernate consulta o banco de dados para cada inserção. Altere esse valor e pronto.
hibernate.id.new_generator_mappings
configuração é muito importante. Eu espero que seja a configuração padrão que eu não tenha que gastar muito tempo pesquisando por que o número de id fica selvagem.