sql >> Database teknologi >  >> RDS >> PostgreSQL

dvale kunne ikke hente næste sekvensværdi

Hibernates PostgreSQL-dialekt er ikke særlig lysstærk. Den kender ikke til dine per-SERIAL-sekvenser og antager, at der er en global database-dækkende sekvens kaldet "hibernate_sequence", som den kan bruge.

(OPDATERING :Det ser ud til, at nyere Hibernate-versioner kan bruge standardsekvenserne pr. tabel, når GenerationType.IDENTITY er angivet. Test din version, og brug denne i stedet for nedenstående, hvis den virker for dig.)

Du skal ændre dine tilknytninger for eksplicit at angive hver sekvens. Det er irriterende, gentagne og 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 er ret vigtigt. Hvis du udelader det, vil Hibernate blindt antage, at sekvensen er defineret med INCREMENT 50 så når den får en værdi fra en sekvens, kan den bruge den værdi og de 49 værdier under den som unikke genererede nøgler. Hvis dine databasesekvenser stiger med 1 - standarden - vil dette resultere i unikke overtrædelser, da Hibernate forsøger at genbruge eksisterende nøgler.

Bemærk, at det vil at få én nøgle ad gangen resultere i en ekstra rundtur pr. indsats. Så vidt jeg kan se, er Hibernate ikke i stand til at bruge INSERT ... RETURNING for effektivt at returnere genererede nøgler, og den kan tilsyneladende heller ikke bruge den JDBC-genererede nøglegrænseflade. Hvis du beder den bruge en sekvens, kalder den nextval for at få værdien insert det eksplicit, hvilket resulterer i to rundrejser. For at reducere omkostningerne ved det, kan du indstille en større stigning på nøglesekvenser med masser af inserts , og husk at indstille det på kortlægningen og den underliggende databasesekvens. Det får Hibernate til at kalde nextval sjældnere og cache blokke af nøgler til at dele ud efterhånden.

Jeg er sikker på, at du kan se fra ovenstående, at jeg ikke er enig i Hibernate-designvalgene, der er foretaget her, i det mindste ud fra perspektivet ved at bruge det med PostgreSQL. De skal bruge getGeneratedKeys eller ved at bruge INSERT ... RETURNING med DEFAULT for nøglen, lader databasen tage sig af dette, uden at Hibernate behøver at bekymre sig om navnene på sekvenserne eller eksplicit adgang til dem.

BTW, hvis du bruger Hibernate med Pg, vil du muligvis også have en oplock-trigger til Pg for at tillade Hibernates optimistiske låsning at interagere sikkert med normal databaselåsning. Uden det eller noget lignende vil dine Hibernate-opdateringer have en tendens til at blokere ændringer foretaget via andre almindelige SQL-klienter. Spørg mig, hvordan jeg ved det.



  1. Hvordan fungerer indeksering

  2. Opret forbindelse til en MySQL-server over SSH i PHP

  3. Hvordan administrerer man bedst historiske opslagsværdier i en database?

  4. Sådan fungerer LIKE-operatøren i MySQL