Почему генератор Hibernate по умолчанию для PostgreSql «SequenceGenerator», а не «IdentityGenerator»? - PullRequest
7 голосов
/ 27 февраля 2012

Генератором идентификаторов по умолчанию для Postgresql в Hibernate является SequenceGenerator [1]. т. е. Hibernate будет делать SELECT nextval('hibernate_sequence') для генерации идентификатора перед выполнением INSERT foo (id, ...) VALUES (123, ...) при фиксации сеанса.

Однако PostgreSql поддерживает столбцы идентификаторов автоинкремента (см., Например, [2]), и генератором по умолчанию для всех других баз данных, поддерживающих автоинкремент, является использование этой функции [3], а также для выполнения вставок, пропускающих значение идентификатора, и для запроса база данных для нового идентификатора (до фиксации сеанса, но внутри транзакции сеанса).

Я видел недавнее обсуждение [4], согласно которому прежняя стратегия в целом лучше из-за несоответствия вставки перед сессией.

Если SequenceGenerator лучше (согласно [4]), почему он не используется по умолчанию для баз данных, которые его поддерживают (см. [3])?

Если IdentityGenerator лучше, почему PostgreSql явно выбирает SequenceGenerator, когда Postgres поддерживает первый (согласно [2])?

Я попытался найти историю решения переопределить значение по умолчанию на диалекте Postgres (см. [1]), но не смог найти соответствующий коммит в GitHub. Я следовал за кодом обратно в SVN-репозиторий, но след остывает, когда файл PostgreSQLDialect добавляется на r11563 с бесполезным сообщением коммита «maven миграции» [5]. Я не могу следовать истории дальше. Может кто-нибудь найти коммит, который добавил это переопределение? Возможно, в сообщении о фиксации есть дополнительная информация.

Заранее спасибо.

[1] https://github.com/hibernate/hibernate-orm/blob/master/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQL81Dialect.java#L267

[2] Автоинкремент PostgreSQL

[3] https://github.com/hibernate/hibernate-orm/blob/master/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java#L639

[4] http://nhforge.org/blogs/nhibernate/archive/2009/03/20/nhibernate-poid-generators-revealed.aspx

[5] https://source.jboss.org/browse/Hibernate/core/trunk/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java?focusedRev=14993&fromRev=11563&toRev=14993#r14993

Ответы [ 2 ]

2 голосов
/ 28 февраля 2012

Возможно, потому что генераторы afterInsert обычно не работают для PG в NHibernate, потому что он использует стиль выходных параметров OracleStyle, который не поддерживается драйвером npgsql-ADONET, который возвращает результат как результат запроса, а не как параметр out.

SQL: INSERT INTO .... возвращение идентификатора в nhoutparameter;: nhoutparameter = null;

при использовании Oracle это работает

command.Execute();
object id =  command.Parameter["nhoutparameter"].Value;
Assert.NotNull(id);

в PG нет.Это должно быть

object id = command.ExecuteScalar();
0 голосов
/ 28 февраля 2012

Это всего лишь предположение, поскольку я не могу найти хорошую документацию по функциям / версиям на postgres, но ...

Возможно, диалект postgres был добавлен до того, как был реализован последовательный, стабильный, широко используемый, или разработчики, которые реализовалидиалект знал об этом.Изменение генератора идентификатора по умолчанию для диалекта было бы серьезным изменением, и это плохо.

...