Java Persistence API i złożony klucz główny częściowy

0

Potrzebuję skonsultować moją radosną twórczość w zakresie baz danych i JPA.

Dotychczas tworzyłem swoje dzieło za pomocą JDBC i zapytań SQL budowanych ręcznie. Wraz z pomysłem by przejść na interfejs web zobaczyłem jak to fajnie tworzy się poprzez JPA, ale ja już swoją bazę mam zaprojektowaną i zrobiłem w niej nietypowe rozwiązanie do archiwizacji danych.
Dodałem do tabeli w kluczu złożonym pole editcount, które za każdym razem tworzy nową kopię wpisu ze zmianami, ale jak robię powiązanie z innymi tabelami, to z klucza obcego usuwam powiązanie z editcount tej tabeli (każda tabela ma swój editcount w swoim kluczu głównym).

Pytanie jakie mi się nasunęło po kilku tutorialach, to czy da się w JPA zamodelować taką budowę relacji między tabelami? Czy może jednak zmienić sposób archiwizacji przeprowadzanych operacji na tabelę bieżącą i tabelę historyczną? Albo może jest jakieś gotowe rozwiązanie do przechowywania takich informacji pozwalające łatwo odbudować stan wpisu z dowolnego momentu?

0

Dodałem do tabeli w kluczu złożonym pole editcount, które za każdym razem tworzy nową kopię wpisu ze zmianami, ale jak robię powiązanie z innymi tabelami, to z klucza obcego usuwam powiązanie z editcount tej tabeli (każda tabela ma swój editcount w swoim kluczu głównym).

Nie wiem o co chodzi.

Czy może jednak zmienić sposób archiwizacji przeprowadzanych operacji na tabelę bieżącą i tabelę historyczną? Albo może jest jakieś gotowe rozwiązanie do przechowywania takich informacji pozwalające łatwo odbudować stan wpisu z dowolnego momentu?

A co konkretnie chcesz zrobić? O jaką archiwizację chodzi?

0

@JulianR: o ile zrozumiałem, to masz relacje w bazie oraz zdefiniowane PK/FK z edit_count + przechowujesz historię zmian?

screenshot-20220114081930.png

Nie rozumiem jak robię powiązanie z innymi tabelami, to z klucza obcego usuwam powiązanie z editcount tej tabeli. W bazie PK/FK jest ALBO nie ma. Nie może być "trochę".
Gdzie to powiązanie robisz? W bazie? Przy korzystaniu z JPA?

Co do historii zmian, może szukasz czegoś w stylu https://hibernate.org/orm/envers/ (+ jak inni z tego korzystają) ?

0

@yarel: FK jest częścią PK child, ale wywalam parent_edit_count. Jak coś się zmienia w Parent, to dodaje nowy wpis z edit count++ a child pozostaje bez zmian. Działa to dobrze z widokami. do wyciągania aktualnej wersji wpisów w tabeli Parent i daje wygodny wgląd w poprzednie wersje wpisu.

Ale JPA w Springu kusi, więc zastanawiam się, czy nie zrezygnować z tego "sprytnego" rozwiązania, bo domyślam się, że to wychodzi poza standardowe opisy relacji między tabelami.

Envers to dokładnie to, czego chciałem. Dzięki za wskazówkę.

2

@JulianR: masz na to proste rozwiązanie

Najpierw klucz

@Embeddable
class VersionedId implements Serializable{
   private int id;
   private int version;
}

Ta klasa będzie reprezentować klucze złożone z ID i wersji. Można jej uzyć tak:

@Entity
class Parent{
    @EmbeddedId
    private VersionedId id
} 

Potem masa

Następnym krokiem jest stworzenie klasy, która będzie modelować zależność z wykorzystaniem złożonego klucza obcego:

@Entity
class Child{
    @EmbeddedId
    private VersionedId id

    @JoinColumns({
        @JoinColumn(name="parent_id", referencedColumnName="id"),
        @JoinColumn(name="parent_version", referencedColumnName="version")
    })
  @OneToOne
  private Parent parent;

}

I to powinno ładnie zaskoczyć. Jeżeli nie, to wróć z treścią błędu, bo pisałem prosto z głowy, a problem nie jest powszechny.

1 użytkowników online, w tym zalogowanych: 0, gości: 1