Liệt kê trong Hibernate


82

Thường hữu ích khi có một trường trong DAO có giá trị đến từ kiểu liệt kê Java. Một ví dụ điển hình là một DAO đăng nhập nơi bạn thường có một trường đặc trưng cho người dùng là "BÌNH THƯỜNG" hoặc "QUẢN TRỊ VIÊN". Trong Hibernate, tôi sẽ sử dụng 2 đối tượng sau để thể hiện mối quan hệ này theo cách an toàn (semi-) typeafe:

class User {
    String username;
    String passwd;
    UserType type;
}

class UserType {
    private enum Type {ADMIN, NORMAL};
    private String type;

    //Setters/Getters for Hibernate
    public void setType(String type);
    public String getType();

    //Setters/Getters for user
    public void setUserType(UserType.Type t);
    public UserType.Type getUserType();

    public static UserType fromType(UserType.Type t);
}

Điều này hoạt động, nhưng tôi thấy lớp UserType không phù hợp và đòi hỏi quá nhiều sự quan liêu chỉ để lưu trữ một vài giá trị. Tốt nhất, Hibernate nên hỗ trợ trực tiếp các trường enum và sẽ tạo thêm một bảng để lưu trữ các giá trị kiểu liệt kê.

Câu hỏi của tôi là: Có cách nào để ánh xạ trực tiếp một lớp liệt kê trong Hibernate không? Nếu không, mô hình của tôi để biểu diễn các bảng liệt kê có đủ tốt hay tôi đang thiếu thứ gì đó? Người ta sử dụng những mẫu nào khác?

Câu trả lời:


110

sử dụng chú thích ngủ đông hoặc JPA:

class User {
   @Enumerated(EnumType.STRING)
   UserType type
}

UserType chỉ là một enum java 5 tiêu chuẩn.

Tôi không thể tưởng tượng điều này chỉ giới hạn ở các chú thích nhưng tôi thực sự không biết cách thực hiện việc này với các tệp hbm. Nó có thể rất phụ thuộc vào phiên bản, tôi đoán nhưng tôi khá chắc chắn rằng 3.2+ chế độ ngủ đông là bắt buộc.

chỉnh sửa: có thể trong hbm, nhưng hơi lộn xộn, hãy xem chủ đề diễn đàn này


3
@Enumerated (EnumType.ORDINAL) có thể ánh xạ tới int nào hiệu quả hơn không?
Lee Chee Kiam

4
có lẽ là hiệu quả hơn, nhưng tôi đã bỏ tiền ra vì không thể đo lường sự khác biệt trong một hệ thống thực. EnumType.ORDINAL thực sự là mặc định nếu bạn chỉ sử dụng @Enumerated. Tôi nghĩ rằng hầu hết mọi người (đặc biệt là DBA) có xu hướng thích tên enum trong DB.
Gareth Davis

1
Làm cách nào để thay đổi độ dài cột cho các ô này? Tôi đã thử thêm chú thích Cột nhưng điều đó không được chấp nhận?
Kannan Ekanath

2
Bạn cần hỏi điều đó như một câu hỏi khác.
Gareth Davis

2
Sử dụng STRING thay vì ORDINAL vì nó cho phép bạn thêm các phần tử bổ sung vào Enum bất kể thứ tự.
Matthew Daumen

14

Từ tài liệu Hibernate: http://www.hibernate.org/272.html

Bạn có thể tạo một typedef mới cho mỗi enums của mình và tham chiếu các typedef trong thẻ thuộc tính.

Lập bản đồ ví dụ - nội tuyến <type> thẻ

  <property name='suit'>
    <type name="EnumUserType">
      <param name="enumClassName">com.company.project.Suit</param>
    </type>
  </property>

Lập bản đồ ví dụ - sử dụng <typedef>

  <typedef name="suit" class='EnumUserType'>
      <param name="enumClassName">com.company.project.Suit</param>
  </typedef>

  <class ...>
    <property name='suit' type='suit'/>
  </class>

Cảm ơn. Tôi đã biết về giải pháp đó rồi. Vấn đề là nó yêu cầu tất cả các enums của bạn phải sử dụng loại nội bộ ngủ đông, điều này có thể dẫn đến sự cố nếu bạn đang sử dụng DAO làm DTO như trong trường hợp của tôi. Một giải pháp tốt hơn là thực sự được mô tả ở đây: hibernate.org/273.html
Georgios Gousios

1
Lưu ý rằng trong các phiên bản mới hơn, tên tham số được enumClassthay thế enumClassName.
Ryan Ransford
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.