2013-08-27 63 views
13

Tôi gặp vấn đề mà tôi không thể xoay sở được. Trong chế độ ngủ đông Tôi không có vấn đề với những điều sau đây:EclipseLink và Prencelocation Sequence Generator

@GeneratedValue(strategy = GenerationType.AUTO, generator = "email-seq-gen") 
@SequenceGenerator(name="email-seq-gen", sequenceName="EMAIL_SEQ_GEN", allocationSize=500) 

Sau đó, trong schema.ddl của tôi, tôi có điều này:

CREATE SEQUENCE EMAIL_SEQ_GEN START 1 INCREMENT 500; 

Không có nhiều để xem ở đây. Mọi thứ hoạt động như mong đợi. Tuy nhiên, nếu tôi chuyển sang nhà cung cấp của tôi để EclipseLink tôi nhận được lỗi này:

The sequence named [EMAIL_SEQ_GEN] is setup incorrectly. Its increment does not match its pre-allocation size. 

Vì vậy, tất nhiên tôi google xung quanh và thấy một cái gì đó về EclipseLink tạo ra một số âm nếu giá trị ban đầu là 1 và rằng nó phải bằng các allocationSize.

Vì vậy, được rồi, vì vậy hãy thêm "initialValue = 500" và cập nhật tập lệnh DDL của tôi thành "START 500", nhưng bây giờ số của tôi bắt đầu ở mức 500 thay vì 1. Số cho? Đây có phải là lỗi EclipseLink hay không có điều gì đó mà tôi không hiểu. Tôi muốn tạo các chuỗi bắt đầu từ 1 và có kích thước phân bổ được điều chỉnh theo thực thể (trong trường hợp này là 500). Làm thế nào tôi sẽ làm điều đó với EclipseLink?

Cảm ơn!

Một cách khác để hỏi này .... cho DDL này:

CREATE SEQUENCE EMAIL_SEQ_GEN START 1 INCREMENT 500; 

cách chính xác để chú thích thực thể của tôi để sử dụng nó với EclipseLink là gì?

Nếu tôi để EclipseLink tạo DDL của tôi thì đây:

@GeneratedValue(strategy = GenerationType.AUTO, generator = "email-seq-gen") 
@SequenceGenerator(name="email-seq-gen", sequenceName="EMAIL_SEQ_GEN", initialValue=1, allocationSize=500) 

sẽ tạo ra điều này:

CREATE SEQUENCE EMAIL_SEQ_GEN INCREMENT BY 500 START WITH 500; 

Những loại ngụ ý rằng nó là không thể để tạo ra một DDL với một "BẮT ĐẦU VỚI 1 "bằng cách sử dụng EclipseLink.

+0

Nếu bạn đi theo hướng khác (hãy để EclipseLink tạo DDL từ các thực thể của bạn) nó tạo ra cái gì? – DannyMo

+0

Tôi đã chỉnh sửa bài đăng gốc để thêm câu trả lời cho câu hỏi của bạn. –

Trả lời

18

Theo thực thể mặc định được chú thích bằng @SequenceGenerator, hãy sử dụng initialValue = 1 và sắp xếpSize = 50.

public @interface SequenceGenerator { 
    /** 
    * (Optional) The value from which the sequence object 
    * is to start generating. 
    */ 
    int initialValue() default 1; 

    /** 
    * (Optional) The amount to increment by when allocating 
    * sequence numbers from the sequence. 
    */ 
    int allocationSize() default 50; 
} 

A "tuần tự" id thực thể dường như được tính bằng cách EclipseLink với công thức sau:

entityId = initialValue - allocationSize + INCREMENT_BY 

hoặc trong trường hợp sử dụng DDL:

entityId = START_WITH - allocationSize + INCREMENT_BY 

Trở lại với cụ thể của bạn trường hợp:


@SequenceGenerator( 
    name="email-seq-gen", 
    sequenceName="EMAIL_SEQ_GEN", 
    allocationSize=500 
) // initialValue=1 (default) 

CREATE SEQUENCE EMAIL_SEQ_GEN START WITH 1 INCREMENT BY 500; 

sản xuất

entityId = 1 - 500 + 1 = -500 // EclipseLink error 

@SequenceGenerator( 
    name="email-seq-gen", 
    sequenceName="EMAIL_SEQ_GEN", 
    initialValue=1, 
    allocationSize=500) 

CREATE SEQUENCE EMAIL_SEQ_GEN START WITH 1 INCREMENT BY 500; 

sản xuất

entityId = 1 - 500 + 1 = -500 // EclipseLink error 

@SequenceGenerator( 
    name="email-seq-gen", 
    sequenceName="EMAIL_SEQ_GEN", 
    initialValue=500, 
    allocationSize=500 
) 

CREATE SEQUENCE EMAIL_SEQ_GEN START WITH 500 INCREMENT BY 500; 

sản xuất

entityId = 500 - 500 + 500 = 500 // fine, but inappropriate 
entityId = 500 - 500 + 1000 = 1000 // incremented by 500 
entityId = 500 - 500 + 1500 = 1500 // incremented by 500 
... 

Để đáp ứng yêu cầu của bạn sau một nên được sử dụng:

@SequenceGenerator( 
    name="email-seq-gen", 
    sequenceName="EMAIL_SEQ_GEN", 
    allocationSize=500 
) // initialValue=1 (default) but 'START WITH'=500 

CREATE SEQUENCE EMAIL_SEQ_GEN START WITH 500 INCREMENT BY 1; 

sản xuất

entityId = 500 - 500 + 1 = 1 
entityId = 500 - 500 + 2 = 2 
entityId = 500 - 500 + 3 = 3 
... 

Một chuỗi hiện tại có thể được loại bỏ khỏi cơ sở dữ liệu cơ bản như sau SQL command:

DROP SEQUENCE email_seq_gen RESTRICT; 

Tôi hy vọng điều đó sẽ hữu ích.

+0

Thật tuyệt khi biết cách xóa/xóa chuỗi đã tạo. Tôi đã thử một số cách tiếp cận nhưng không ai trong số họ đang làm việc. – burseaner

+0

@burseaner: Tôi đã thêm lệnh thả chuỗi đang tồn tại. – wypieprz

+1

Tạo chuỗi với số gia số 1 là sai. EclipseLink chỉ gọi trình tự một lần cho mỗi đợt phân bổ (trong trường hợp này một lần cho mỗi 500 thực thể được thêm vào trong cùng một giao dịch). Do đó số gia tăng phải bằng 500. Có, số sẽ bị bỏ qua khi phân bổ hàng loạt nhỏ hơn 500, nhưng đó là giá bạn trả cho hiệu quả nhờ ít lời gọi hơn của chuỗi. Để xem lỗi xảy ra, thêm hai thực thể, sau đó chấm dứt chương trình Java, sau đó thêm một thực thể khác. Một java.sql.SQLIntegrityConstraintViolationException sẽ xảy ra do một ID trùng lặp. – bgh

2

chuỗi của bạn nên bắt đầu từ 500 không 1. Nếu bạn bắt đầu từ 1, sau đó các NEXTVAL đầu tiên sẽ chỉ cung cấp cho bạn 1 id thay vì 500.

Nếu không gọi NEXTVAL trên dãy sau khi thiết lập, vì vậy nó được gửi đến 501.

Lỗi có phải là cảnh báo hoặc lỗi không? Nếu bạn chỉ cần bỏ qua nó nó vẫn hoạt động?

+1

Điều đó có ý nghĩa như thế nào? Nếu tôi viết mã để nhận dạng hồ bơi, tôi nhận được 1, 501, 1001, v.v. Đây cũng là những gì tôi nhận được từ Hibernate? Nếu đây không phải là trường hợp với EclipseLink và (từ googling xung quanh) nó xuất hiện nhiều người đã có một vấn đề với điều này tại sao họ không chỉ sửa chữa thuật toán này? –

+0

Ồ, đó là lỗi không phải là cảnh báo. –