2012-07-01 6 views
9

Znalazłem problem z używaniem prymitywu jako obiektu @Id dla JPA w połączeniu z JPA Spring Data. Mam relacji rodzic/dziecko z Cascade.ALL na stronie nadrzędnej, a dziecko ma PK, który w tym samym czasie jest również FK rodziców.Zawsze używaj prymitywnych oblewów obiektów dla JPA @Id zamiast typu pierwotnego?

class Parent { 
    @Id 
    private long id; 

    @OneToOne(mappedBy = "parent", cascade = ALL) 
    private Child child; 
} 

class Child { 
    @Id 
    @OneToOne 
    private Parent parent; 
} 

Więc, kiedy biegnę:

... 
Parent parent = new Parent(); 
Child child = new Child(parent); 
parent.setChild(child); 
em.persist(parent) 
... 

wszystko działa poprawnie. Ale kiedyś Wiosna danych WZP utrzymują się podmiot, więc biegnę zamiast:

parentRepository.save(parent); // instead of em.persist(parent); 

i ten był nie powiodło się z następującym wyjątkiem:

Caused by: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: Parent 

Problem polegał na tym, że wiosna danych JPA save () Metoda sprawdza, czy jednostka jest nowa, a jeśli jest nowa, to jest używana em.persist() w innym przypadku użyto em.merge().

Interesującą częścią tutaj jak czeki Wiosna czy jednostka jest nowy lub nie:

getId(entity) == null; 

I, oczywiście, to był fałszywy, bo użyłem długo jak typ dla @Id, a wartość domyślna na długo wynosi 0. Kiedy zmieniłem długą na długą, wszystko działa również z Spring Data JPA.

Tak więc zalecaną praktyką jest zawsze używanie oblewek obiektów dla typów pierwotnych (takich jak długie zamiast długich) zamiast typów pierwotnych. Wszelkie zasoby stron trzecich opisujące to jako zalecaną praktykę byłoby bardzo miłe.

+0

Dzięki za udostępnienie nam tych informacji. –

+0

możliwy duplikat [Primitive lub wrapper dla hibernacji kluczy podstawowych] (http://stackoverflow.com/questions/3535791/primitive-or-wrapper-for-hibernate-primary-keys) – stevedbrown

Odpowiedz

12

Powiedziałbym, że tak, zaleca się stosowanie typów obiektów zamiast prymitywów ze względu na przypadek, który widzisz. Nie ma możliwości rozróżnienia, czy jednostka jest nowa, czy też istniejąca wcześniej z prymitywnym identyfikatorem. Używam hibernacji od lat i zawsze używam obiektów do identyfikatorów.

+1

+1, absolutnie się zgadzam – Raman

0

Chciałbym użyć typu obiektu. W odwzorowaniu XML można umieścić atrybut "niezapisane wartości", ale nie sądzę, że istnieje bezpośrednie tłumaczenie adnotacji. W rezultacie bezpieczniej jest trzymać się typów obiektów.

A większość programistów oczekiwałaby, że wartość "null" w identyfikatorze będzie oznaczać niezapisane mimo to.

Powiązane problemy