Proszę wyjaśnić o insertable = false i updatable = false w odniesieniu do adnotacji JPA @Column

151

Jeśli pole jest opatrzone adnotacją insertable=false, updatable=false, czy nie oznacza to, że nie możesz wstawić wartości ani zmienić istniejącej wartości? Dlaczego chcesz to zrobić?

@Entity
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToMany(mappedBy="person", cascade=CascadeType.ALL)
    private List<Address> addresses;
}

@Entity
public class Address {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @ManyToOne
    @JoinColumn(name="ADDRESS_FK")
    @Column(insertable=false, updatable=false)
    private Person person;
}
Thang Pham
źródło

Odpowiedzi:

121

Zrobisz to, gdy odpowiedzialność za tworzenie / aktualizowanie danego podmiotu powiązanego nie leży w bieżącej encji. Np. Masz a Personi Address. Chcesz dodać insertable=false, updatable=falsedo @OneToManyrelacji z Personjednostką w Addressencji, po prostu dlatego, że nie jest odpowiedzialna za Addresstworzenie lub aktualizowanie pliku Person. Jest odwrotnie.

BalusC
źródło
Odnosi się do definiowania insertable=false,updatable=falsepo jednej ze stron relacji.
BalusC
3
Mówisz, że z updatable = false na Person wyłączy aktualizację Person.name podczas aktualizacji adresu (nie zgadzam się, ponieważ jest to celem kaskady). Mówisz również, że definicja @Column robi coś innego, gdy jej klucz obcy (Person) i gdy nie jest kluczem obcym (ponieważ nie ma odniesienia do jednostki, do której można by wyłączyć aktualizację). Czytając javadoc pod kątem aktualizacji, powiedziałbym, że po prostu uniemożliwi zmianę osoby dla danego adresu, jeśli zostanie utrwalony. Czy możesz wyjaśnić?
Flowy
8
Myślę, że chciałeś powiedzieć ... to the @ManyToOne relationship with the ...?
Martin Konecny,
111

Definiowanie insertable=false, updatable=falsejest przydatne, gdy trzeba odwzorować pole więcej niż raz w encji, zazwyczaj:

To IMO nie jest kwestią semantyczną, ale zdecydowanie techniczną.

Pascal Thivent
źródło
15
Jestem głęboko przekonany, że ta odpowiedź jest znacznie lepsza niż zaakceptowana. Przyjęta odpowiedź daje poczucie, że atrybut, który można wstawiać / aktualizować, ma związek z tworzeniem / aktualizacją powiązanego obiektu, podczas gdy prawdziwym zamiarem tych atrybutów jest zapobieganie wstawianiu / aktualizowaniu kolumny w bieżącej encji. Tworzenie / aktualizację powiązanego podmiotu zajmuje się kaskadowym atrybutem adnotacji mapowania.
Jayant
25

Chciałbym dodać do odpowiedzi BalusC i Pascala Thiventa inne powszechne użycie insertable=false, updatable=false:

Rozważmy kolumnę, która nie jest identyfikatorem, ale jakimś numerem kolejnym . Odpowiedzialność za obliczenie numeru kolejnego niekoniecznie musi należeć do aplikacji.

Na przykład numer kolejny zaczyna się od 1000 i powinien być zwiększany o jeden dla każdej nowej jednostki. Jest to łatwe i bardzo trafne w bazie danych iw takich przypadkach takie konfiguracje mają sens.

Magnilex
źródło
1
Sekwencje są również obsługiwane przez JPA, więc możesz zdefiniować swoją sekwencję również za pomocą adnotacji JPA.
eis
8

Innym przykładem może być kolumna „created_on”, w której chcesz, aby baza danych obsługiwała tworzenie daty

Johny19
źródło
Czy Hibernate ma blokować aktualizacje na podstawie możliwej do zaktualizowania = fałszywej adnotacji? W moim repozytorium JPA test kolumna created_on z tą adnotacją akceptuje aktualizacje bez reklamacji.
chrisinmtown
1
@chrisinmtown Eclipselink w ogóle nie uwzględni kolumny w sql. Spodziewam się, że tak samo jest z Hibernate
Jaqen H'ghar