O dialeto PostgreSQL do Hibernate não é muito brilhante. Ele não sabe sobre suas sequências por SERIAL e está assumindo que há uma sequência global em todo o banco de dados chamada "hibernate_sequence" que ele pode usar.
(ATUALIZAÇÃO :Parece que as versões mais recentes do Hibernate podem usar as sequências padrão por tabela quando
GenerationType.IDENTITY
é especificado. Teste sua versão e use isso em vez do abaixo se funcionar para você.) Você precisa alterar seus mapeamentos para especificar explicitamente cada sequência. É chato, repetitivo e inútil.
@Entity
@Table(name = "JUDGEMENTS")
public class Judgement implements Serializable, Cloneable {
private static final long serialVersionUID = -7049957706738879274L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="judgements_id_seq")
@SequenceGenerator(name="judgements_id_seq", sequenceName="judgements_id_seq", allocationSize=1)
@Column(name = "JUD_ID")
private Long _judId;
...
O
allocationSize=1
é bastante importante. Se você omitir, o Hibernate assumirá cegamente que a sequência está definida com INCREMENT 50
então, quando ele obtém um valor de uma sequência, ele pode usar esse valor e os 49 valores abaixo dele como chaves geradas exclusivas. Se as sequências do seu banco de dados aumentarem em 1 - o padrão - isso resultará em violações exclusivas, pois o Hibernate tenta reutilizar as chaves existentes. Observe que obter uma chave de cada vez vai resultar em uma viagem de ida e volta adicional por pastilha. Até onde eu sei, o Hibernate não é capaz de usar
INSERT ... RETURNING
para retornar chaves geradas com eficiência, nem aparentemente pode usar a interface de chaves geradas por JDBC. Se você disser para usar uma sequência, ele chamará nextval
para obter o valor, insert
isso explicitamente, resultando em duas viagens de ida e volta. Para reduzir o custo disso, você pode definir um incremento maior nas sequências de teclas com muitas inserções, lembrando de defini-lo no mapeamento e a seqüência de banco de dados subjacente. Isso fará com que o Hibernate chame nextval
com menos frequência e blocos de chaves em cache para distribuir à medida que avança. Tenho certeza que você pode ver acima que não concordo com as escolhas de design do Hibernate feitas aqui, pelo menos da perspectiva de usá-lo com o PostgreSQL. Eles devem estar usando
getGeneratedKeys
ou usando INSERT ... RETURNING
com DEFAULT
para a chave, deixando o banco de dados cuidar disso sem que o Hibernate tenha que se preocupar com os nomes das sequências ou acesso explícito a elas. BTW, se você estiver usando o Hibernate com Pg, possivelmente também desejará um gatilho oplock para Pg para permitir que o bloqueio otimista do Hibernate interaja com segurança com o bloqueio normal do banco de dados. Sem ele ou algo parecido, suas atualizações do Hibernate tenderão a atrapalhar as alterações feitas por meio de outros clientes SQL regulares. Pergunte-me como eu sei.