2013-08-13 67 views
36

Thỉnh thoảng tôi tìm thấy chúng cùng nhau, đôi khi một mình ... những lúc khác chúng có vẻ giống nhau.Sự khác biệt giữa @GeneratedValue và @GenericGenerator

Sự khác biệt là gì?

Dưới đây là ba ví dụ. Họ làm gì khác nhau? Tại sao tôi không thể sử dụng @GeneratedValue cho tất cả chúng?

Ví dụ 1

@Id 
@GeneratedValue(generator="increment") 
@GenericGenerator(name="increment", strategy = "increment") 
Long id; 

Ví dụ 2

@Id @GeneratedValue(strategy=GenerationType.SEQUENCE) 
private int userId; 

Ví dụ 3

@ElementCollection 
@JoinTable(name="Address", 
    [email protected](name="user_id") 
) 
@GenericGenerator(name="hilo-gen", strategy="hilo") 
@CollectionId(columns = @Column(name="Address_id"), generator = "hilo-gen", type = @Type(type="long")) 
Collection<Addr> listOfAddresses = new ArrayList<Addr>(); 

Trả lời

63

Khi sử dụng một ORM nó thường là cần thiết để tạo ra một giá trị khóa chính.

Chú thích @GeneratedValue biểu thị rằng giá trị cho cột, phải được chú thích bằng @Id được tạo. Các phần tử strategygenerator trên chú thích mô tả cách thu được giá trị được tạo.

Có bốn giá trị có thể cho các phần tử strategy trên @GeneratedValue chú thích: IDENTITY, AUTO, TABLESEQUENCE. See more.

Vì vậy, để trả lời Phần 2 câu hỏi của bạn, đoạn mã cho biết giá trị của userId sẽ được lấy thông qua một chuỗi trong cơ sở dữ liệu.

Phần tử generator của chú thích @GeneratedValue biểu thị tên của trình tạo khóa chính. Trong Part1 câu hỏi của bạn, đoạn mã cho biết rằng generator có tên increment sẽ được sử dụng để lấy giá trị khóa chính. increment sau đó được xác định trong chú thích tiếp theo @GenericGenerator. @GenericGenerator là chú thích ngủ đông được sử dụng để biểu thị trình tạo tùy chỉnh, có thể là một lớp hoặc lối tắt đến trình tạo được cung cấp bởi Hibernate. increment là một phím tắt để một máy phát điện Hibernate rằng:

tạo ra định danh của loại dài, ngắn hoặc int mà là duy nhất chỉ khi không có quá trình khác được chèn dữ liệu vào cùng một bảng. Không sử dụng sử dụng trong một cụm.

Trong Phần thứ ba câu hỏi của bạn, mã sử dụng một máy phát điện hilo Hibernate rằng:

sử dụng một thuật toán hi/lo để tạo ra hiệu quả định danh kiểu dài, ngắn hoặc int, được cung cấp một bảng và cột (theo mặc định là hibernate_unique_key và next_hi tương ứng) dưới dạng nguồn hi giá trị. Thuật toán hi/lo tạo các mã định danh duy nhất chỉ có cho một cơ sở dữ liệu cụ thể.

+1

câu trả lời rất tốt nhất định. – Krishna

2
@Entity 
@Table(name="Honey") 
public class Honey implements Serializable{ 
    private static final long serialVersionUID = 42L; 
    @Id 
    //@SequenceGenerator(name="honeySequence",sequenceName="HONEY_SEQ") 
    @org.hibernate.annotations.GenericGenerator(name="honeySequence", strategy = "sequence", 
    parameters = { 
      @Parameter(name="sequence", value="HONEY_SEQ") } 
    ) 
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="honeySequence") 
    private int Id; 
    private String name; 
    private String taste; 
  • @GeneratedValue chỉ được sử dụng để có được những giá trị tạo ra. Hai đối số chiến lượcmáy phát điện được sử dụng để xác định cách thu được giá trị.
  • @GenericGenerator được sử dụng để ánh xạ trình tạo trình tự do người dùng xác định với phiên ngủ đông của bạn.
  • Bạn cũng có thể sử dụng @SequenceGenerator mà tôi đã nhận xét trong mã của mình. Đây không phải là trình tạo chuỗi đơn giản mà là trình tạo hoạt động trên thuật toán HILO. Do đó bạn sẽ tìm thấy rất nhiều khoảng trống trong chuỗi của bạn, giống như giá trị đầu tiên của bạn sẽ bắt đầu từ 50 vì kích thước phân bổ mặc định là 50.

Vì vậy, nó tốt hơn để sử dụng @GenericGenerator cho kiến ​​trúc của riêng bạn. Nhưng nếu bạn buộc phải sử dụng @SequenceGenerator, bạn phải chỉnh sửa chuỗi theo cách thủ công để có hai thuộc tính khác allocSize = 1initialValue = 1. Và để làm việc với các thuộc tính bạn cần phải thêm apropert trong hibernate.cfg.xml tập tin của bạn

<property name="hibernate.id.new_generator_mappings">true</property> 
2

Để mở rộng câu trả lời của @ kevin-Bowersox của.
Mối quan hệ giữa các chiến lược thế hệ khóa chính Hibernate và máy phát điện cụ thể tương ứng, theo quy định tại org.hibernate.id.IdentifierGeneratorFactory

static { 
    GENERATORS.put("uuid", UUIDHexGenerator.class); 
    GENERATORS.put("hilo", TableHiLoGenerator.class); 
    GENERATORS.put("assigned", Assigned.class); 
    GENERATORS.put("identity", IdentityGenerator.class); 
    GENERATORS.put("select", SelectGenerator.class); 
    GENERATORS.put("sequence", SequenceGenerator.class); 
    GENERATORS.put("seqhilo", SequenceHiLoGenerator.class); 
    GENERATORS.put("increment", IncrementGenerator.class); 
    GENERATORS.put("foreign", ForeignGenerator.class); 
    GENERATORS.put("guid", GUIDGenerator.class); 
    GENERATORS.put("uuid.hex", UUIDHexGenerator.class); //uuid.hex is deprecated 
    GENERATORS.put("sequence-identity", SequenceIdentityGenerator.class); 
} 

Mười hai chiến lược trên, cộng với native, mười ba chiến lược thế hệ hỗ trợ trong Hibernate theo mặc định.

Ví dụ với native:

@GeneratedValue(generator = "nativeGenerator") 
@GenericGenerator(name = "nativeGenerator", strategy = "native") 
Các vấn đề liên quan