2011-01-15 16 views

Trả lời

17

GORM là trình bao bọc xung quanh Hibernate (ít nhất đó là một trong những triển khai - hiện cũng có nhiều triển khai NoSQL khác nhau như Redis). Bằng cách đặt autoFlush thành true, bạn sẽ từ chối Hibernate cơ hội tối ưu hóa các cuộc gọi mà nó thực hiện cho cơ sở dữ liệu. Ví dụ, bạn có thể làm cho nó chèn sau đó cập nhật sau đó, khi một chèn đơn có thể là đủ. Không có gì là xấu về điều đó, nó chỉ là không cần thiết và ít hiệu quả hơn. Hibernate đủ thông minh để biết khi nào cần ghi vào cơ sở dữ liệu và có thể tối ưu hóa - bạn đã trừu tượng hóa vấn đề đó.

Đặt failOnError sẽ khiến lưu để ném ngoại lệ bất cứ khi nào bạn cố lưu một đối tượng miền không xác thực. Khi xây dựng một ứng dụng có liên quan đến việc tạo các đối tượng từ đầu vào của người dùng, nó khá bình thường đối với các đối tượng không xác nhận hợp lệ - đầu vào bị thiếu, định dạng sai, vv. . save() trả về đối tượng khi đối tượng đã được lưu thành công hoặc bằng cách khác, cung cấp cho bạn cách thuận tiện hơn để xử lý xác thực như là một phần của luồng ứng dụng, thay vì đặt các khối try-catch khắp nơi.

Peter Ledbrook (trên trong những tác giả của Grails trong hành động) đã viết một loạt lớn các bài báo 'GORM Gotchas', trong đó ông thảo luận về một số vấn đề chi tiết hơn - cũng đáng đọc: part 1, part 2 & part 3.

+2

+1, Những bài viết của Ledbrook là những thứ tốt. Man, nếu những người đã có sẵn một vài năm trước đó, tôi đã được cứu một thế giới đau đớn ... –

+0

Câu trả lời rất hữu ích. Vì vậy, thực sự câu trả lời trực tiếp và chính xác cho câu hỏi về autoFlush là: Không có bất kỳ. – Fletch

+0

@Fletch đôi khi nó có ý nghĩa để đặt 'grails.gorm.failOnError = true'. Cụ thể, nếu các đối tượng của bạn luôn luôn (hoặc gần như luôn luôn) hợp lệ, thì điều này giúp bạn kiểm tra giá trị trả về của 'save()' –

11

Tôi sử dụng cả hai và tin rằng tôi có lý do tuyệt vời mà tôi muốn chia sẻ với bạn.

Tại sao sử dụng grails.gorm.autoFlush = true?

Nguyên nhân không thực sự lưu thực thể/tên miền khi tôi gọi save() là không làm những gì tôi đang yêu cầu API thực hiện. Nó gây ra nhiều đau đầu khi Hibernate tuôn ra trên 16 dòng trước khi thực hiện và nó mang lại đau đớn để gỡ lỗi. Nhóm của bạn không phải là nhà phát triển Java, rất nhiều nỗi đau. Các Grails đã mượn mẫu Active Record Pattern từ Ruby (mà các phương thức persistence được gọi trực tiếp, như domain.save) nhưng Ruby thực sự thực hiện persistance khi save() được gọi, nhưng Grails không vì chúng ẩn 'Hibernate Session 'từ người dùng/nhà phát triển API. Đó là một số Leak Abstraction thất bại của GORM mà chúng tôi có thể giải quyết với thông số cấu hình này.

Sau khi được cài đặt, nếu bạn thực sự cần Mẫu đơn vị công việc của Hibernate, chuỗi này gọi các cuộc gọi SQL và thực hiện một lần vì lý do hiệu suất, chỉ cần sử dụng domain.save(flush:false) khi cần.

Tại sao sử dụng grails.gorm.failOnError = true?

Không bao giờ ẩn ngoại lệ của người dùng. Tất cả các lập trình Java tuyệt vời đều biết điều đó. Nếu bạn "thực sự thực sự" cần phải ẩn, đăng nhập nó như cảnh báo. Nhưng điều bất hạnh này không xảy ra khi Grails xác nhận không thành công (không đăng nhập!) Và làm cho các lập trình viên bị mù, điều gì đó thực sự khó khăn đối với những người mới không biết điều đó. Những người có kinh nghiệm nhất chỉ nói 'thật dễ dàng để tinh chỉnh' nhưng nó chỉ là một luẩn quẩn hơn là cách tốt hơn.

Vì lợi ích, những trừu tượng rò rỉ GORM này là lời phàn nàn duy nhất tôi đã có với Grails trong quá khứ. Ngày nay, họ đã đi với params cấu hình này.

0

đẹp loạt bài viết của Peter Ledbrook về GORM:

Mặc dù tôi không đồng ý với ông về những gì các phiên Hibernate tuôn ra không. Ông nói rằng "Các tuôn ra: lực lượng thực sự Hibernate để tồn tại tất cả các thay đổi cơ sở dữ liệu ngay lập tức". Vâng, điều đó sẽ chỉ xảy ra trong một bối cảnh không giao dịch, bởi vì khi bạn ở trong một giao dịch, các câu lệnh #SQL được flushed từ phiên Hibernate, sẽ được thực thi trong phân đoạn rollback của RDBMS giao dịch của bạn. Vì vậy, họ sẽ không bị bắt nạt cho đến khi giao dịch được thực hiện. Khi trong giao dịch bạn đang thực hiện các hoạt động khác liên quan đến DB, như gửi email xác nhận, bạn muốn biết nếu có bất kỳ ràng buộc hoặc lỗi thời gian chạy DB nào không được khai báo rõ ràng trong quá trình xác thực của bạn đã xảy ra trước đó hay không, ví dụ: bạn đã gửi email xác nhận đó.

Lời khuyên của tôi là chiến lược autoFlush (grails.gorm.autoFlush = true) không sai đối với mỗi lần truy cập. Bạn phải đưa ra quyết định kỹ thuật abouth cho dù bạn muốn sử dụng nó hay không ngay từ đầu, vì vậy các nhà phát triển có thể viết mã của họ cho phù hợp vì họ sẽ biết nếu việc tuôn ra phải được thực hiện một cách rõ ràng hoặc Hibernate sẽ làm điều đó cho họ vào cuối bạn phương thức giao dịch.

Một trường hợp sử dụng phổ biến khác cần xem xét là nếu bạn muốn thực hiện thao tác theo lô bằng GORM. Nếu bạn không xóa phiên Hibernate của bạn mọi số lượng hoạt động SQL, bạn sẽ gặp phải vấn đề.

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