2012-03-25 18 views
15

Mam klasy z następującą definicję:Hibernacja generuje ujemne wartości id przy użyciu sekwencji

@Id 
@SequenceGenerator(name = "SEQ_ACE_WORKERS_QUEUE_STATS_ID", sequenceName = "SEQ_ACE_WORKERS_QUEUE_STATS_ID", allocationSize = 500) 
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_ACE_WORKERS_QUEUE_STATS_ID") 
@Column(name = "ID") 
private long Id; 

Kiedy prowadził ją na JBoss 4.2.3 to działało dobrze i generowane właściwego identyfikatora (od 1000+)

Teraz przenieśliśmy się do jboss 7.1.1 i generuje on negatywne identyfikatory! (począwszy od -498 i przechodzenia w górę)

Każdy pomysł, dlaczego tak się stanie?

+1

czy sprawdziłeś, jaka jest aktualna sekwencja w Oracle i monitorujesz wyjście hibernacji, jeśli widzisz, że wybrałeś następną sekwencję zapytań i jeśli skopiujesz wklej do sqlplus, uzyskasz poprawny/taki sam/oczekiwany wynik? – HRgiger

Odpowiedz

24

Właśnie napotkałem ten problem podczas migracji z JBoss 6.1 do JBoss 7.1.

Według JBoss AS 7.1 dokumentacji JPA (https://docs.jboss.org/author/display/AS71/JPA+Reference+Guide#JPAReferenceGuide-Persistenceunitproperties)

JBoss 7,1 automatycznie ustawia kilka właściwości hibernacji. Jedną z ustawianych właściwości jest hibernate.id.new_generator_mappings, która aktywuje nowe generatory identyfikatorów, które używają różnych algorytmów i nie są kompatybilne wstecz. Ustawienie tej właściwości na false w pliku persistence.xml przywróci zachowanie starego generatora identyfikatorów.

Dokumentacja hibernacji 4 zawiera również informacje dotyczące nowych generatorów identyfikatorów: http://docs.jboss.org/hibernate/core/4.0/manual/en-US/html_single/#mapping-declaration-id-generator.

Dokumentacja hibernacji wyraźnie stwierdza, że ​​nowe generatory identyfikatorów nie są domyślnie włączone, ale, jak wspomniano powyżej, JBoss 7.1 automatycznie je włącza.

+0

Dzięki za odpowiedź, już udało mi się ją znaleźć, zapomniałem zaktualizować ją tutaj :( – Tomer

+0

Począwszy od wersji Hibernate 5.0, właściwość 'hibernate.id.new_generator_mappings' przyjmuje wartość' true'. Patrz http: //docs.jboss .org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html # identyfikatory-generatory –

12

Ustawianie hibernate.id.new_generator_mappings do false w moim persistence.xml była tylko pierwsza część rozwiązania mojego problemu:

Aby całkowicie rozwiązać problem dodałem allocationSize do 1 w @SequenceGenerator (co ja z pominięciem).

30

Nowe zachowanie jest następujących:

AllocationSize to gama podstawowych kluczowych wartości zarezerwowanych dla Hibernate. I wybierz seq.nextval z dual będzie wykonane tylko po hibernacji zużyte ten zakres podstawowych kluczy.

Więc musi zadeklarować taką samą wartość zarówno allocationSize (Hibernate) oraz sekwencję increment by (dB)

Kiedy jawnie ustawić allocationSize=500, np Oracle

create sequence SEQ_ACE_WORKERS_QUEUE_STATS_ID 
     MINVALUE 1 
     MAXVALUE 999999999999999999999999999 
     START WITH 1 
     INCREMENT BY 500 
     NOCACHE 
     NOCYCLE; 

W przeciwnym razie, można zauważyć wartości ujemne lub błędy więzów podniesione z DB z powodu pierwotnych kluczowych kolizji.

Po zrestartowaniu serwera aplikacji zauważysz "skok" między ostatnim przydzielonym kluczem podstawowym a "nowym" numerem kolejnym wybranym przy ponownym uruchomieniu.

Uwaga końcowa: wartość domyślna to 50. Więc jeśli nie podasz allocationSize na stronie hibernacji, musi zadeklarować increment by 50 po stronie DB.

+0

Bardzo przydatna odpowiedź, ponieważ ta informacja najwyraźniej nie znajduje się w dokumentach Hibernacji. –

Powiązane problemy