Obecnie mamy problem (znanej jeden) z Spring Data JPA
+ Spring Data REST
(Hibernate
jako JPA
realizacji) podczas próby aktualizacji zbiórki (relacja), który jest nie po stronie właściciela.Wiosna danych REST + JPA usunąć z kolekcji OneToMany [nie właściciel bocznej]
Odwzorowanie jest następujące:
@Entity(name = Product.NAME)
public class Product {
...
@OneToMany(mappedBy = "baseProduct", fetch = FetchType.LAZY, targetEntity = Variant.class)
List<Variant> getVariants() {
...
i po drugiej stronie Wariant:
@Entity(name = Variant.NAME)
public class Variant extends Product {
...
@ManyToOne(fetch = FetchType.LAZY, targetEntity = Product.class)
@JoinColumn(name = "baseproduct_id", referencedColumnName = "id")
Product getBaseProduct() {
...
}
wszystko jest dobry na stronie Java jeśli używasz Spring Data JPA
tylko jednak jeśli chcesz zaktualizować "produkt", aktualizując jego kolekcję wariantów i wysyłając żądanie PATCH
do https://localhost:8112/storefront/rest/product/21394435410197232 zawierające ładunek nowa kolekcja tylko (o 2 z 3 pozycji):
{"variants":["22801810293768080","22801810293768096"]}
otrzymuję żadnych wyjątków ani nic, ale skoro strona będącym właścicielem jest druga strona nie jest utrwalane i mam starą 3 items
ponownie.
I know
że mogę rozwiązać ten problem przez ustawienie
@JoinColumn(name = "baseproduct_id", referencedColumnName = "id")
na obustronnie i nie używać mappedBy
wszędzie, jednak słyszałem, że jest implikacja wydajność których nie jestem pewien, jak duży jest to (mamy 100+ encji mających @OneToMany
) i zastanawiam się, czy istnieje lepsze obejście przez słuchacza @PreUpdate
czy coś takiego?
Dzięki, jednak obecnie nie chcę usuwać sierot, chcę tylko usunąć "połączenie", nie usuwając żadnej strony :) Również nie jestem wielkim fanem kaskady i być może brakuje mi coś, ale metody addXXX i removeXXX będą w jakiś sposób wywoływane przez Spring Data Rest? – JOKe
Następnie masz złe mapowanie, ponieważ nie podano '@ JoinTable'. Jeśli masz tabelę sprzężenia, najlepszym sposobem na odwzorowanie jest mapowanie tabeli łączenia jako jednostki pośredniej, która ma 2 asocjacje '@ManyToOne'. Mam przykład w mojej książce [High-Performance Java Persistence] (https://leanpub.com/high-performance-java-persistence). –