Spring Data JPA i UUID przy update

Spring Data JPA i UUID przy update
WE
  • Rejestracja:około 7 lat
  • Ostatnio:ponad 5 lat
  • Postów:53
0

Witam,
stworzyłem sobie dla sprawdzenia jak działa UUID i myślałem, że przy każdym update mojej encji do DB UUID pozostanie takie samo, a tutaj zaskoczenie... Robię to tak:

Kopiuj
@Entity
@Getter
@Setter
@NoArgsConstructor
public class Sample {

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

    @Column(updatable = false, unique = true)
    private UUID uuid = UUID.randomUUID();
    private Long age;

    public Sample(Long age) {
        this.age = age;
    }

}
Kopiuj
    @PutMapping("/{id}")
    public Sample updateSample(@RequestBody Sample sample, @PathVariable Long id) {
        sampleDao.findById(id)
                .ifPresent(sample1 -> sample.setId(sample1.getId()));

        return sampleDao.save(sample);
    }

To ucinek z controllera, używam tu JpaRepository.. No i przy każdym pucie moje UUID się zmienia czego nie chcę. Co to powoduje?

MrMadMatt
  • Rejestracja:ponad 9 lat
  • Ostatnio:dzień
  • Postów:373
0

Ustawiaj UUID'a setterem. Nie jestem pewien ale przy zaciągnięciu encji z bazy chyba nie bierze tego zapisanego w bazie tylko generuje przez private UUID uuid = UUID.randomUUID(); aczkolwiek mogę się mylić. Sprawdź.

AK
  • Rejestracja:prawie 7 lat
  • Ostatnio:około miesiąc
  • Postów:3561
0
MrMadMatt napisał(a):

Ustawiaj UUID'a setterem. Nie jestem pewien ale przy zaciągnięciu encji z bazy chyba nie bierze tego zapisanego w bazie tylko generuje przez private UUID uuid = UUID.randomUUID(); aczkolwiek mogę się mylić. Sprawdź.

Coś z tych rzeczy.
Generalnie encja JPA to nie jest taki-se obiekt javowski i wszystko mu wolno, ale ma swoje ograniczenia, inicjowanie pół chyba jest jednym z nich


Bo C to najlepszy język, każdy uczeń ci to powie
CountZero
  • Rejestracja:prawie 8 lat
  • Ostatnio:12 miesięcy
  • Postów:262
0

Te pole jest nadpisywane przy każdej inicjalizacji obiektu, to nie ma prawa mieć stałej wartości. Ponadto @Column(updatable = false) z tego co widzę działa tylko na zapytania UPDATE generowane przez Hibernate'a.

WE
  • Rejestracja:około 7 lat
  • Ostatnio:ponad 5 lat
  • Postów:53
0

Czyli pozostaje mi ustawiać to setterem, a nie w taki sposób?
Tylko wtedy umożliwiam komuś zmianę takiego UUID.

edytowany 1x, ostatnio: weiss
danek
  • Rejestracja:ponad 10 lat
  • Ostatnio:7 miesięcy
  • Lokalizacja:Poznań
  • Postów:797
0

Przecież już teraz masz setter do tego pola.

Ale jeśli chcesz żeby każda instancja miała losowe UUID to w odpowiednim konstruktorze to zapewnij. Ewentualnie statyczną metodą tworzącą (czy jak to się tam nazywa)


Spring? Ja tam wole mieć kontrole nad kodem ᕙ(ꔢ)ᕗ
Haste - mała biblioteka do testów z czasem.
WE
  • Rejestracja:około 7 lat
  • Ostatnio:ponad 5 lat
  • Postów:53
0

Konstruktor też tego nie załatwi, bo przy robieniu Put'a i tak będę musiał pobrać UUID poprzedniej wersji i użyć settera na tej nowej - inaczej zostanie tam null. Przynajmniej tak mi się wydaje.

CountZero
  • Rejestracja:prawie 8 lat
  • Ostatnio:12 miesięcy
  • Postów:262
0

No ale co chcesz właściwie zrobić? Mieć w bazie losowe UUID którego nie możesz nadpisać? Imo bez sensu bo masz już id obiektu co tutaj pełni tą samą role co UUID.

A jak już musisz to zapisuj UUID tylko podczas tworzenia, zrób pole prywatne, nie dodawaj settera i miej nadzieje że nikt tego nie nadpisze.

OtoKamil
  • Rejestracja:ponad 10 lat
  • Ostatnio:około rok
  • Postów:143
1

Nie edytujesz obiektu tylko tworzysz nowy i przypisujesz mu ID z encji z bazy.
Twój PUT przyjmuje encję jako @RequestBody, które przy inicjalizacji dostaje UUID (bo ustawiłeś generowanie go podczas inicjalizacji -> private UUID uuid = UUID.randomUUID() ). Następnie pobierasz aktualny obiekt z bazy i przypisujesz temu nowemu (z requesta) jego ID, a potem go zapisujesz - stąd bierze się twój problem.

Nie używaj encji do takich rzeczy. Stwórz sobie np. UpdateSampleRequest (DTO) i w nim określ jakie pola są możliwe do aktualizacji i taki obiekt sobie przyjmij w @RequestBody, potem sobie przemapuj na pola encji (ręcznie lub jakimś mapperem, feel free). Możesz też rzućić okiem na "Validation Groups" jeśli chcesz spróbować innego podejścia i mieć bardziej "uniwersalne" DTO (ale tego używałem raz czy dwa.

@CountZero

Kopiuj
A jak już musisz to zapisuj UUID tylko podczas tworzenia, zrób pole prywatne, nie dodawaj settera i miej nadzieje że nikt tego nie nadpisze.

Ma ustawione updatable=false, to go chroni przed zaktualizowaniem pola (nie dostanie exceptionem w twarz jak ktoś to spróbuje nadpisać, po prostu nie wejdzie to do bazy i tyle). Z setterami się zgadzam, możesz wyrzucić.

@MrMadMatt UUID wyciągane jest z bazy poprawnie

edytowany 6x, ostatnio: OtoKamil
CountZero
Masz racje, nie leci exception.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.