PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

hibernacja nie mogła uzyskać następnej wartości sekwencji

Dialekt PostgreSQL w Hibernate nie jest zbyt jasny. Nie wie o twoich sekwencjach dla poszczególnych serii i zakłada, że ​​istnieje globalna sekwencja w całej bazie danych o nazwie „hibernate_sequence”, której może użyć.

(AKTUALIZUJ :Wygląda na to, że nowsze wersje Hibernate mogą używać domyślnych sekwencji dla tabeli, gdy GenerationType.IDENTITY jest specyficzne. Przetestuj swoją wersję i użyj tego zamiast poniższego, jeśli działa dla Ciebie.)

Musisz zmienić swoje mapowania, aby wyraźnie określić każdą sekwencję. To denerwujące, powtarzalne i bezcelowe.

@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 jest bardzo ważne. Jeśli go pominiesz, Hibernate ślepo założy, że sekwencja jest zdefiniowana za pomocą INCREMENT 50 więc gdy otrzyma wartość z sekwencji, może użyć tej wartości i 49 wartości pod nią jako unikalne wygenerowane klucze. Jeśli sekwencje w Twojej bazie danych zwiększają się o 1 — wartość domyślna — spowoduje to unikalne naruszenia, ponieważ Hibernate będzie próbował ponownie użyć istniejących kluczy.

Pamiętaj, że uzyskanie jednego klucza naraz będzie skutkować dodatkową podróżą w obie strony na wkładkę. O ile wiem, Hibernate nie jest w stanie użyć INSERT ... RETURNING skutecznie zwracać wygenerowane klucze, ani najwyraźniej nie może używać interfejsu wygenerowanych kluczy JDBC. Jeśli powiesz mu, aby używał sekwencji, wywoła nextval aby uzyskać wartość, a następnie insert to wyraźnie, co skutkuje dwiema podróżami w obie strony. Aby zmniejszyć ten koszt, możesz ustawić większy przyrost w sekwencjach klawiszy z dużą ilością wstawek , pamiętając o ustawieniu tego w mapowaniu i podstawowa sekwencja bazy danych. To spowoduje, że Hibernate wywoła nextval rzadziej i bloki kluczy w pamięci podręcznej do rozdawania w miarę postępu.

Na pewno widać z powyższego, że nie zgadzam się z dokonanymi tutaj wyborami projektowymi Hibernate, przynajmniej z perspektywy używania go z PostgreSQL. Powinni używać getGeneratedKeys lub używając INSERT ... RETURNING z DEFAULT dla klucza, pozwalając bazie danych zająć się tym bez konieczności zajmowania się przez Hibernate nazwami sekwencji lub jawnym dostępem do nich.

BTW, jeśli używasz Hibernate z Pg, prawdopodobnie będziesz potrzebować wyzwalacza opozycji dla Pg, aby umożliwić optymistycznemu blokowaniu Hibernate bezpieczną interakcję z normalnym blokowaniem bazy danych. Bez tego lub czegoś podobnego twoje aktualizacje Hibernate będą miały tendencję do blokowania zmian dokonywanych za pośrednictwem innych zwykłych klientów SQL. Zapytaj mnie, skąd wiem.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak zainstalować postgres z NSIS ze wszystkimi parametrami?

  2. psycopg2 w rzeczywistości nie wstawia danych

  3. Jak rejestrować zapytania PostgreSQL?

  4. Oblicz następny klucz podstawowy - o określonym formacie

  5. Używanie aktualnego czasu w UTC jako wartości domyślnej w PostgreSQL