2012-02-27 24 views
7

Trình tạo mã định danh mặc định cho Postgresql trong Hibernate là SequenceGenerator [1]. tức là Hibernate sẽ làm SELECT nextval('hibernate_sequence') để tạo ID trước khi thực hiện một cam kết phiên INSERT foo (id, ...) VALUES (123, ...). Tuy nhiên, PostgreSql hỗ trợ các cột id tự động (xem ví dụ [2]), và trình tạo mặc định cho tất cả các cơ sở dữ liệu khác hỗ trợ autoincrement là sử dụng tính năng đó [3], và thực hiện chèn bỏ giá trị id và truy vấn cơ sở dữ liệu cho id mới (trước cam kết phiên, nhưng trong giao dịch của phiên).Tại sao trình tạo mặc định Hibernate cho PostgreSql là "SequenceGenerator" chứ không phải "IdentityGenerator"?

Tôi đã thấy một số cuộc thảo luận gần đây [4] gợi ý rằng chiến lược trước đây tốt hơn nói chung, do sự không khớp trước đó của phiên chèn trước.

Nếu Trình tự tạo luồng là tốt hơn (theo [4]), tại sao nó không phải là mặc định cho các cơ sở dữ liệu hỗ trợ nó (xem [3])?

Nếu IdentityGenerator tốt hơn, tại sao PostgreSql lại chọn SequenceGenerator một cách rõ ràng khi Postgres hỗ trợ cũ (theo [2])?

Tôi đã cố gắng tìm lịch sử của quyết định ghi đè lên mặc định trong phương ngữ Postgres (xem [1]), nhưng tôi không thể tìm thấy cam kết có liên quan trong GitHub. Tôi đã theo mã trở lại kho lưu trữ SVN, nhưng dấu vết đi vào nơi mà tệp PostgreSQLDialect được thêm vào tại r11563 với một thông báo cam kết vô ích về "di chuyển maven" [5]. Tôi dường như không thể theo lịch sử nữa. Bất cứ ai có thể tìm thấy cam kết mà thêm ghi đè này? Có lẽ có nhiều thông tin hơn trong thông điệp cam kết.

Xin cảm ơn trước.

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

[2] PostgreSQL Autoincrement

[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

+3

Tôi giả định điều này là do kiểu dữ liệu 'nối tiếp' chỉ là một" chuỗi trong ngụy trang ". –

+0

Điều đó không giải thích được - tất cả các cột tự động là các chuỗi trong ngụy trang. – Rich

+0

không, không phải cho SQL Server hoặc MySQL, nơi bạn không thể nhận được giá trị tiếp theo mà không thực hiện việc chèn (đó là sự khác biệt lớn giữa giải pháp dựa trên chuỗi và "tự động tăng") –

Trả lời

2

Có thể vì máy phát điện sau thường bị hỏng cho PG trong NHibernate vì nó sử dụng kiểu tham số ngoài OracleStyle không được trình điều khiển npgsql-ADONET hỗ trợ trả về kết quả dưới dạng kết quả truy vấn và không tham số.

SQL: INSERT INTO .... trả lại id thành thông số nhout; : nhoutparameter = null;

sử dụng Oracle công trình này

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

trong PG không. Nó phải là

object id = command.ExecuteScalar(); 
+0

Điều này có ý nghĩa đối với NHibernate. Bạn có biết nếu áp dụng tương tự cho Hibernate? – Rich

+0

có thể. tôi không có môi trường ở đây để kiểm tra. Đối với NH tôi chỉ có nguồn và chạy UnitTests chống lại PG. Tất cả các bài kiểm tra postInsertGenerator không thành công. Bạn có thể làm tương tự với Hibernatesource từ github chạy với PG. – Firo

0

Đây chỉ là suy đoán kể từ khi tôi không thể tìm thấy tài liệu tính năng/phiên bản tốt trên postgres nhưng ...

Có thể phương ngữ postgres đã được thêm trước khi nối tiếp được triển khai, ổn định, được sử dụng rộng rãi hoặc các nhà phát triển đã thực hiện phương ngữ đã biết. Thay đổi trình tạo mã định danh mặc định cho một phương ngữ sẽ là một thay đổi đột phá và những thay đổi đó là xấu.

Các vấn đề liên quan