2016-06-09 13 views
5

Hầu hết Kotlin JPA dụ mã trông như thế nàyKotlin với JPA/Hibernate: không lười tải mà không có `mở`?

class Person(val name: String, val age: Int) { /* ... */ } 

hoặc thậm chí

data class Person(val name: String="", val age: Int=0) { /* ... */ } 

Bây giờ, Hibernate User Guide, và tôi cũng nghĩ nhiều ORMs khác, tiểu bang mà họ thường muốn tạo proxy hoặc mở rộng lớp mô hình, nhưng để cho phép điều đó trong Kotlin, lớp học phải được định nghĩa rõ ràng open. Điều này là không thể với các lớp dữ liệu và tôi giả sử, đánh giá từ kinh nghiệm của riêng tôi, rằng hầu hết mọi người không nghĩ về nó khi viết các thực thể JPA trong Kotlin.

Vì vậy, đến câu hỏi của tôi (đây là stackoverflow sau khi tất cả), nó là đủ để làm

open class Person(val name: String, val age: Int) { /* ... */ } 

hoặc chúng tôi sẽ thực sự phải làm

open class Person(open val name: String, open val age: Int) { /* ... */ } 

không không cần thiết cản trở việc ORM khi thực hiện công việc của mình đúng cách?
Nếu nó thực sự có hại, có lẽ chúng tôi nên đề xuất thêm cảnh báo cho IntelliJ IDEA, rằng nếu một lớp học có chú thích @Entity, nó phải được xác định open.

+0

Tôi không thấy từ "có hại" được áp dụng tại đây như thế nào. Bạn có thể làm rõ việc sử dụng nó hay xóa nó khỏi câu hỏi nếu nó không quan trọng? – voddan

+0

Chủ yếu là thực tế ít nhất Hibernate không thể lười biếng tải lớp học cuối cùng hoặc có phương pháp truy cập cuối cùng và sử dụng lớp dữ liệu cho JPA thường giống như một điều tốt để làm, nhưng thực sự có thể làm tổn thương hiệu suất, bởi vì họ là cuối cùng theo định nghĩa (tại thời điểm này ít nhất, nghe nói rằng có thể thay đổi). Tiêu đề là rất clickbaity, bởi vì tôi nghĩ rằng đó phải là một cái gì đó phổ biến hơn và ngăn chặn ví dụ. các ứng dụng được chuyển đến Kotlin có hiệu suất kém hơn so với đối tác Java và người dùng đổ lỗi cho Kotlin:/ – johnp

+0

Cảm ơn bạn đã diễn giải câu hỏi! – voddan

Trả lời

6

Các hướng dẫn mà bạn cung cấp quy định cụ thể:

Các lớp thực thể phải có một công hoặc bảo vệ không tham số nhà xây dựng ... Giao diện có thể không được thiết kế như một thực thể ... Các lớp thực thể không phải thức . Không có phương thức hoặc biến mẫu cố định nào của lớp thực thể có thể là cuối cùng.

Các lớp Kotlin tuân thủ quy ước JavaBeans dành cho người định cư/getters.

Nếu ORM của bạn có những yêu cầu như trên, sau đó bạn thực sự phải chỉ rõ open trên lớp và phương pháp của nó:

open class Person(open val name: String = "", 
        open val age: Int = 0) 

Các giá trị mặc định cho tất cả các thông số nhà xây dựng cho phép Kotlin để tạo thêm một sản phẩm nào constructor. Hoặc bạn có thể cung cấp cho nó như là một nhà xây dựng thứ cấp:

open class Person(open val name: String, open val age: Int) { 
    constructor() : this("", 0) 
} 

Lưu ý rằng open val tạo ra một trường cuối cùng riêng và một getter mở. Nếu không đủ, hãy sử dụng chú thích như @JvmField open val name.

Các ORM giống như bạn sử dụng có thêm ma sát với mã Kotlin do các mẫu thiết kế có vấn đề mà họ sử dụng (như tạo mọi thứ không phải là cuối cùng).

Tùy chọn tốt là sử dụng ORM riêng cho Kotlin. Ví dụ Exposed được hỗ trợ bởi JetBrains và được sử dụng cho một số sản phẩm của mình, mà nói cho chính nó. Một tùy chọn khác là Ebean chính thức hỗ trợ Kotlin (nhờ @johnp)

+1

Cảm ơn bạn đã trả lời! Một trong những điều khiến tôi cảm thấy kỳ quặc là các lớp học cuối cùng không thể lười biếng trong Hibernate và tôi tưởng tượng rằng có thể làm tổn thương nghiêm trọng hiệu suất nếu không được cân nhắc. Cá nhân tôi đã chuyển sang [Ebean] (https://ebean-orm.github.io/) cách đây vài tuần, vì nó đề cập rõ ràng Kotlin và có hàng rào cản trở thấp hơn Hibernate, nhưng tôi chưa nghe nói về Exposed và chắc chắn sẽ xem xét nó. – johnp

+0

Tải xuống có nghĩa là Hibernate chỉ cần tải dữ liệu khi trình thu thập được gọi lần đầu tiên. Tuy nhiên, getter đã được thực hiện bởi một lập trình viên (như một trường đọc đơn giản)! Do đó, Hibernate cần phải thay đổi chức năng của phương thức đó để nó thăm dò ý kiến ​​của JDBC tại thời gian gọi. Bạn có thể thay đổi một phương thức bằng cách sửa đổi bytecode ở giai đoạn biên dịch, hoặc bằng cách mở rộng động lớp và ghi đè các bộ định tuyến. –

+0

Nếu bạn muốn xem xét một ORM đặc biệt của Kotlin, https://github.com/mvysny/vok-orm có thể là một lựa chọn tốt. Nó vẫn sử dụng POJO có thể, ví dụ: được chú thích bằng các chú thích JSR303 và chuyển qua các biểu mẫu web; nó sử dụng Sql2o đằng sau hậu trường; nó tập trung vào Kotlin là ngôn ngữ đích duy nhất. Disclaimer: Tôi là tác giả. –

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