2011-10-17 19 views
14

Trong đậu POJO Java mã như vậy có thể có lợi, đặc biệt là với các bộ sưu tập:Có thực hành tốt để khởi tạo các trường bên trong trình thu thập thực thể JPA không?

class POJO { 
    private Collection<X> col; 

    public Collection<X> getCol() { 
     if (col == null) 
      col = new SomeCollection<X>(); 

     return col; 
    } 
} 

Nó làm cho có thể cho các mã sử dụng POJO gọi pojo.getCol().isEmpty() mà không có một kiểm tra null bổ sung, do đó làm cho mã rõ ràng hơn.

Giả sử lớp POJO là thực thể JPA, vẫn an toàn để làm điều đó? Bằng cách khởi tạo bộ sưu tập từ null thành rỗng, dữ liệu liên tục sẽ không bị thay đổi, nhưng vẫn còn, chúng ta đang sửa đổi đối tượng và do đó nhà cung cấp kiên trì có thể chạy một số tác dụng phụ khi xóa ngữ cảnh kiên trì. Chúng ta có nguy cơ gì? Tính di động có thể?

Trả lời

10

Tôi sẽ không khuyến khích khởi tạo lười biếng cho các thuộc tính trong thực thể ORM.

Chúng tôi gặp phải vấn đề nghiêm trọng khi khởi tạo lười biếng thuộc tính tổ chức bằng Hibernate, vì vậy tôi sẽ không khuyến khích mạnh mẽ. Vấn đề chúng tôi đã thấy được thể hiện bằng cách tiết kiệm khi chúng tôi phát hành yêu cầu tìm kiếm. Điều này là do khi đối tượng được nạp thuộc tính là null, nhưng khi getter được gọi nó sẽ trả về đối tượng khởi tạo lười biếng để hibernate (đúng) coi đối tượng bị bẩn và sẽ lưu nó trước khi phát hành tìm kiếm.

+0

Cảm ơn, đó là những gì tôi đã tìm kiếm - một lời cảnh báo từ ai đó đã bị thiêu làm điều đó. Tôi có linh cảm rằng nó có thể sai, chỉ có tôi muốn chắc chắn rằng tôi không mơ hồ. – MaDa

+1

chắc chắn. Chúng tôi đã mất 2 ngày để theo dõi nơi vật thể trở nên bẩn thỉu. Nó khá đau đớn. – digitaljoel

20

Tôi không coi đó là phương pháp hay, nhiều hơn như một số tối ưu hóa rất hiếm khi cần thiết. Có thể khởi tạo lười biếng có thể có ý nghĩa nếu SomeCollection cực kỳ nặng để tạo ra. Thay vào đó bạn có thể khởi tạo nó khi được khai báo (mã sạch hơn ít nhất là cho đôi mắt của tôi):

class POJO { 
    private Collection<X> col = new SomeCollection<X>(); 

    public Collection<X> getCol() { 
     return col; 
    } 
} 

Không có tác dụng phụ trong các vấn đề về xả hoặc di chuyển và bạn có một lần kiểm tra ít hơn.

2

Nói chung, nên sử dụng các bộ sưu tập rỗng thay thế hoặc null (đối với các trường là bộ sưu tập).

Nhưng tôi không khuyên bạn nên làm theo cách bạn làm trong bộ nạp.

Theo ý kiến ​​cá nhân của tôi, "quy tắc" ở trên cũng nên được sử dụng cho đại diện bên trong của đối tượng. Vì vậy, bạn đi tốt hơn với:

class POJO { 
    private Collection<X> col = new SomeCollection<X>(); 

Dù sao nếu bạn muốn muốn làm cho nó tiết kiệm hơn, bạn cần phải bảo vệ mọi cách bạn cập nhật col tham khảo. Nhưng trong một ứng dụng JPA, đây là một trường hợp sử dụng rất thô.

1

Khởi tạo lười biếng rất phổ biến và tốt để thực hiện.

Có thỏa hiệp so với khởi tạo trong constructor hoặc định nghĩa biến:

Pro

  • khởi Lazy nói chung là hiệu quả hơn, nó trì hoãn chi phí của việc tạo ra giá trị, trong đó có thể không bao giờ được yêu cầu hoặc thay thế bằng một số giá trị khác. Điều này là rất phổ biến trong JPA, nơi mà đối tượng hiện có được đọc từ cơ sở dữ liệu và giá trị của chúng luôn được thay thế.
  • Nó cho phép một giá trị rỗng có ý nghĩa, điều này là điển hình hơn với các giá trị Boolean, trong đó null có nghĩa là mặc định được phân bổ một cách lười biếng dựa trên cái gì khác mà không biết lúc tạo.
  • Nếu giá trị tạm thời hoặc bị vô hiệu hóa một số cách, khởi tạo lười biếng có thể ngăn chặn con trỏ null.

Côn

  • Nếu trường có được truy cập trực tiếp bạn vẫn có thể có được một con trỏ null-.
  • Đặt giá trị mặc định trong định nghĩa biến rõ ràng hơn.
  • Nếu đối tượng được sử dụng đồng thời, khởi tạo lười biếng có thể là vấn đề tương tranh.
Các vấn đề liên quan