sql >> Databasteknik >  >> RDS >> PostgreSQL

hibernate kunde inte hämta nästa sekvensvärde

Hibernates PostgreSQL-dialekt är inte särskilt ljus. Den känner inte till dina per-SERIAL-sekvenser och antar att det finns en global databasomfattande sekvens som kallas "hibernate_sequence" som den kan använda.

(UPPDATERA :Det verkar som att nyare Hibernate-versioner kan använda standardsekvenserna per tabell när GenerationType.IDENTITY är specificerad. Testa din version och använd denna istället för nedan om den fungerar för dig.)

Du måste ändra dina mappningar för att explicit specificera varje sekvens. Det är irriterande, repetitivt och meningslöst.

@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;
...

allocationSize=1 är ganska viktigt. Om du utelämnar det kommer Hibernate blint att anta att sekvensen är definierad med INCREMENT 50 så när den får ett värde från en sekvens kan den använda det värdet och de 49 värdena under det som unika genererade nycklar. Om dina databassekvenser ökar med 1 - standard - kommer detta att resultera i unika överträdelser när Hibernate försöker återanvända befintliga nycklar.

Observera att det kommer att få en nyckel i taget resultera i ytterligare en tur och retur per insats. Såvitt jag kan se kan Hibernate inte använda INSERT ... RETURNING för att effektivt returnera genererade nycklar, inte heller kan den uppenbarligen använda gränssnittet för JDBC-genererade nycklar. Om du säger åt den att använda en sekvens kommer den att anropa nextval för att få värdet insert det uttryckligen, vilket resulterar i två rundresor. För att minska kostnaden för det kan du ställa in en större ökning på nyckelsekvenser med många inserts , kom ihåg att ställa in det på kartläggningen och den underliggande databassekvensen. Det gör att Hibernate anropar nextval mindre ofta och cacheblock med nycklar att dela ut allt eftersom.

Jag är säker på att du kan se från ovanstående att jag inte håller med om designvalen för Hibernate som gjorts här, åtminstone från perspektivet att använda det med PostgreSQL. De bör använda getGeneratedKeys eller med INSERT ... RETURNING med DEFAULT för nyckeln, låta databasen ta hand om detta utan att Hibernate behöver besvära sig över namnen på sekvenserna eller explicit åtkomst till dem.

BTW, om du använder Hibernate med Pg vill du möjligen också ha en oplock-utlösare för Pg för att låta Hibernates optimistiska låsning interagera säkert med normal databaslåsning. Utan det eller något liknande kommer dina Hibernate-uppdateringar att tendera att smutskasta ändringar som görs via andra vanliga SQL-klienter. Fråga mig hur jag vet.



  1. Konvertera siffror till ord i MYSQL-resultat! Använder Query

  2. skalär underfråga i if-satsen Condition i PL/SQL

  3. Vilken är inställningen för att se tidsdelen med datum i Oracle PL/SQL-utvecklare?

  4. Hur hittar du diskstorleken för en Postgres / PostgreSQL-tabell och dess index