2012-02-05 28 views
5

Tôi đã thấy điều này question tại SO có xu hướng hướng tới nguyên thủy và cũng thấy điều này từ coderanch có xu hướng dẫn tới trình bao bọc. Cả hai đều hơi cũ.Tôi có nên sử dụng Primitives hoặc trình bao bọc trong JPA2.0 không?

Tôi không có bất kỳ nhu cầu đặc biệt nào chỉ muốn biết một thực hành tốt tiêu chuẩn.

Ví dụ trên web cũng được trộn lẫn. ví dụ một số có đi như thế này:

@Id 
@Column(name = "CUSTOMER_ID") 
public long customerId; 

Khác với Máy đóng gói:

@Id 
@Column(name = "CUSTOMER_ID") 
public Long customerId; 

Trả lời

6

Sự khác biệt giữa hai là nullability. kiểu nguyên thủy không thể là null, trong khi kiểu "Wrapped" có thể là null.

Tôi thích sử dụng loại bọc vì bạn có thể biết đối tượng đã được lưu/tải vào/từ cơ sở dữ liệu hay không giá trị id là rỗng.

Tôi không nghĩ rằng có một "thực hành tốt nhất" ở đây, có thể là vấn đề về phong cách?

+1

Tôi muốn nói một nullable "savedness" chỉ là rất nhiều một thói quen tốt. (Cho dù đó là ID hay cột phiên bản/dấu thời gian.) – millimoose

+0

+1, một giá trị null là một imin quan trọng. Tôi sử dụng hàm bao trong tất cả các đối tượng thực thể của mình vì cùng một lý do. – Perception

+0

Vì vậy, nó là một wrapper được ưa thích cho phiên bản ID hoặc tem thời gian nhưng không phải cho những người khác? –

1

Nếu bạn sử dụng nguyên thủy, nó sẽ luôn giữ giá trị mặc định, trong trường hợp này là 0L cho lâu, ngay cả khi giá trị không có trong cơ sở dữ liệu. Và nếu bạn sử dụng đối tượng bao bọc, nó sẽ có giá trị null nếu giá trị không có trong cơ sở dữ liệu hoặc thực thể vẫn chưa được duy trì.

+0

IIRC, nếu bạn cố gắng đọc một đối tượng từ cơ sở dữ liệu với một giá trị null trong một cột mà bạn đã ánh xạ tới một thành viên nguyên thủy, bạn sẽ nhận được một lỗi thời gian chạy. Vì vậy, nó nhiều hơn là chỉ chèn các giá trị mặc định. – Bill

0

Tôi nghĩ rằng câu trả lời được bao gồm trong phần tử không có trong chú thích @Column. Nếu nó có thể được nullable hơn gói nguyên thủy là ok. Nhưng trên nullable = false cột (như ID là) nguyên thủy là tốt hơn. Bạn sẽ nhận được kiểm tra thêm bởi vì null không thể được đúc thành int/long.

3

Hibernate khuyên bạn:

Chúng tôi khuyên bạn khai báo thuộc tính nhận dạng một cách nhất quán tên trên lớp dai dẳng và rằng bạn sử dụng một nullable (ví dụ: phi nguyên thủy) gõ. more

+3

Đây chỉ dành cho thuộc tính số nhận dạng chứ không phải đề xuất chung. – joecoder

0

Từ quan điểm Hibernate, nó không thay đổi bất kỳ thứ gì như Hibernate sử dụng cùng kiểu Hibernate đại diện cho chúng.

Tuy nhiên, như được chỉ ra bởi Bytecode Ninja, bạn không thể phân biệt giá trị mặc định của 0 nguyên thủy từ 0 được gán trong khi không có sự mơ hồ có thể với giá trị rỗng (id rỗng luôn có nghĩa là thực thể mới) , đó là lý do tại sao tôi thích sử dụng một loại wrapper nullable.

Và đây là đề xuất Hibernate. Từ Tài liệu tham khảo:

4.1.2. Cung cấp thuộc tính số nhận dạng (tùy chọn)

Mèo có thuộc tính được gọi là id. Thuộc tính này ánh xạ tới cột khóa chính của một bảng cơ sở dữ liệu. Bất động sản có thể đã được gọi là bất cứ điều gì, và loại của nó có thể đã được bất kỳ loại nguyên thủy, bất kỳ nguyên thủy "wrapper" loại, java.lang.String hoặc java.util.Date. Nếu bảng cơ sở dữ liệu kế thừa của bạn có các khóa tổng hợp, bạn có thể sử dụng lớp do người dùng xác định với các thuộc tính của các loại này (xem phần về số nhận dạng tổng hợp sau này trong chương.)

Thuộc tính nhận dạng là tùy chọn hoàn toàn. Bạn có thể để chúng ra và để Hibernate theo dõi các định danh đối tượng trong nội bộ. Tuy nhiên, chúng tôi không khuyến cáo điều này.

Trong thực tế, một số chức năng chỉ dành cho các lớp học tuyên bố một đặc tính nhận dạng:

Transitive reattachment cho các đối tượng tách ra (cập nhật thác hoặc thác merge) - xem Phần 10.11, “kiên trì Transitive” Session.saveOrUpdate () Session.merge() Chúng tôi khuyên bạn nên khai báo các thuộc tính định danh được đặt tên nhất quán trên các lớp liên tục và bạn sử dụng một loại nullable (nghĩa là không nguyên thủy).

Và tôi thực sự tận dụng này trong lớp cơ sở của tôi:

@MappedSuperclass 
public class BaseEntity implements Serializable { 
    private static final long serialVersionUID = 1L; 
    private Long id; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    public Long getId() { 
     return id; 
    } 

    public void setId(Long id) { 
     this.id = id; 
    } 

    @Transient 
    public boolean isNew() { 
     return (this.id == null); 
    } 
} 

Vui lòng kiểm tra thêm chi tiết ở đây: https://stackoverflow.com/posts/3537407/edit

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