PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

hibernate не можа да получи следващата стойност на последователността

PostgreSQL диалектът на Hibernate не е много ярък. Той не знае за вашите per-SERIAL последователности и предполага, че има глобална последователност за цялата база данни, наречена „hibernate_sequence“, която може да използва.

(АКТУАЛИЗИРАНЕ :Изглежда, че по-новите версии на Hibernate може да използват последователностите по подразбиране за таблица, когато GenerationType.IDENTITY е уточнено. Тествайте версията си и използвайте тази вместо по-долу, ако работи за вас.)

Трябва да промените своите съпоставяния, за да посочите изрично всяка последователност. Това е досадно, повтарящо се и безсмислено.

@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 е доста важно. Ако го пропуснете, Hibernate сляпо ще приеме, че последователността е дефинирана с INCREMENT 50 така че когато получи стойност от последователност, може да използва тази стойност и 49-те стойности под нея като уникално генерирани ключове. Ако последователностите на вашата база данни се увеличат с 1 – по подразбиране – това ще доведе до уникални нарушения, тъй като Hibernate се опитва да използва повторно съществуващите ключове.

Имайте предвид, че получаването на един ключ наведнъж ще води до допълнително двупосочно пътуване на вложка. Доколкото мога да кажа, Hibernate не може да използва INSERT ... RETURNING за ефективно връщане на генерирани ключове, нито очевидно може да използва интерфейса на генерираните ключове на JDBC. Ако му кажете да използва последователност, той ще извика nextval за да получите стойността, след това insert това изрично, което води до две двупосочни пътувания. За да намалите цената на това, можете да зададете по-голямо увеличение на ключовите последователности с много вмъквания , като не забравяте да го зададете на картографирането и основната последователност на базата данни. Това ще накара Hibernate да извика nextval по-рядко и кеширайте блокове с ключове, които да раздавате, докато върви.

Сигурен съм, че можете да видите от горното, че не съм съгласен с направените тук избори за дизайн на Hibernate, поне от гледна точка на използването му с PostgreSQL. Те трябва да използват getGeneratedKeys или с помощта на INSERT ... RETURNING с DEFAULT за ключа, оставяйки базата данни да се погрижи за това, без да се налага Hibernate да се затруднява с имената на последователностите или изричен достъп до тях.

BTW, ако използвате Hibernate с Pg, вероятно ще искате и задействане на oplock за Pg, за да позволите на оптимистичното заключване на Hibernate да взаимодейства безопасно с нормалното заключване на базата данни. Без него или нещо подобно, вашите актуализации на Hibernate ще са склонни да разрушат промените, направени чрез други обикновени SQL клиенти. Попитайте ме откъде знам.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да предам парола на pg_dump?

  2. синтаксис на външния ключ на postgresql

  3. Генерирайте sql с подзаявка като колона в оператор select с помощта на SQLAlchemy

  4. postgresql генерира последователност без празнина

  5. Ефективна стратегия за оставяне на одитна следа/история на промените за DB приложения?