• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Adnotacja @Version nie inkrementuje po dodaniu od set'a

VPS Starter Arubacloud
0 głosów
135 wizyt
pytanie zadane 17 marca 2022 w Java przez Lulex Użytkownik (820 p.)

Cześć,

napotkałem problem przy optimistic locku. Do entity dodałem kolumnę version z adnotacją @Version i moje ParkingEntity wygląda następująco:

public class ParkingEntity {
@Id
@Column(name = "parking_id")
private String idParking;
private String name;
private String address;
private int numberOfParkingSlots;
private int numberOfChargers;
private boolean isLPGAllowed;
private Double widthOfSlot;
@OneToMany(mappedBy= "parking")
private Set<CarEntity> cars = new HashSet<>();
@Version
private Long version;

Gdy robię update tego entity to wersjonowanie działa w porządku, version się zwiększa o 1.

Jednak problem pojawia się gdy dodaję do set'a cars jakiś car.

Robię to takimi metodami w ParkingEntity:

public void addCar(CarEntity carEntity) {
    cars.add(carEntity);
    carEntity.setParking(this);
}

public void removeCar(CarEntity carEntity) {
    cars.remove(carEntity);
    carEntity.setParking(null);
}

Jak śledzę to sobie w bazie danych to wszystko działa w porządku, auto wskakuje do set'a i przy CarEntity w kolumnie z parking_id (relacja ManyToOne i mam @JoinColumn(name = "parking_id" private ParkingEntity parking) pojawia się ID parkingu, to niestety wersja się nie zwiększa.

Robię oczywiście parkingRepository.save(parking) i carRepository.save(car) jednak nie mogę nic znaleźć gdzie może być błąd, bo przecież set<car> się zmienia.

1 odpowiedź

0 głosów
odpowiedź 17 marca 2022 przez Wiciorny Ekspert (269,120 p.)
edycja 17 marca 2022 przez Wiciorny

Wersjonowanie się nie podbija, bo kolekcje są immutable, jeśli coś dodajesz- zmiana pozostawia referencje w spokoju przez co nie zachodzi żadna zmiana, i faktycznie u CIebie nie zmieniasz ani nie aktualizujesz encji. 
Zanim zaczniesz korzystać z wersjonowania i @Version, zapoznaj się czym jest ta adnotacja i jak działa

Wszystkie pola i właściwości niebędące powiązaniami oraz wszystkie relacje należące do jednostki są uwzględniane podczas sprawdzania wersji

więc jeśli zmieniłbyś elementy kolekcji :) to  realnie versja się podbija, ale u Ciebie nie robisz nic, 

 

public void addCar(CarEntity carEntity) {
    cars.add(carEntity);
    carEntity.setParking(this);
}

to nie robi nic po za tym, że pozostawia encje w menaged i localnie w cashe zmienia wartość 
robisz save() - widać że nie rozumiesz czym jest hibernate, nie musisz nigdy pisać  obiekt.save() - on i tak zostanie zapisany czy tego chcesz  czy nie :) jeśli odrywasz aktualna encje. 
Hibernate ma w budowany mechanizm dirty checking, który sprawdza czy encja, która wcześniej została pobrana przez Hibernate’a, zmieniła swój stan. Jeśli tak, jest zapisywana do bazy danych. Jeśli nie, to nic się nie dzieje i użycie metody save() nie daje żadnego efektu.
Do czego klucz obcy się odwołuje kiedy piszesz 

  cars.add(carEntity);
    carEntity.setParking(this);

do cars? do carEntity? Do czego klucz ma się odwołać? 
Zapraszam do LEKTURY : 

cascade=CascadeType.PERSIST) 

I CZYM JEST NP.     persist() oraz flush() https://vladmihalcea.com/a-beginners-guide-to-jpahibernate-flush-strategies/

 

Sprawdź na koniec versje w obiekcie cars :) - ona ulega zmianie, bo cars jest aktualizowane, natomiast nie aktualizowany jest Parking

komentarz 17 marca 2022 przez Lulex Użytkownik (820 p.)
Hmmm, coś mam nie tak chyba w tej relacji dwukierunkowej.

Jeśli nie zrobię carRepository.save(entity) to mi nie zapisuje w bazie id parkingu w tabelce z samochodami, mimo, że mam car.setParking(wrzucam tutaj parkingEntity).
komentarz 17 marca 2022 przez Wiciorny Ekspert (269,120 p.)
po prostu nie rozumiesz co robisz... i to jest ten problem, przepisujesz tutorial, czy robisz CRUDA i używasz rzeczy o których działaniu nie masz pojęcia

w jakim stanie jest obiekt ktory przekazujesz do metody? DETACHED? MENAGED? PERSIST? NEW?

:)
komentarz 18 marca 2022 przez Lulex Użytkownik (820 p.)
Hmm skoro mi się nie zmienia bez save'a to wydaje mi się, że detached

Niestety uczę się sam i ciężko niektóre sprawy ogarnąć więc odpalam yt czy jakiś poradnik i robię z przykładem :/ :)
komentarz 18 marca 2022 przez Wiciorny Ekspert (269,120 p.)
edycja 18 marca 2022 przez Wiciorny

blokuje Cię https://www.ibm.com/docs/en/db2/11.5?topic=overview-optimistic-locking
Optimistic locking.
Po drugie twój sam przykład ma mase błędów, i to w 3-4 linijkach kodu, ale to swoją drogą jak bezmyślnie przepisujesz błędne tutoriale, bo nie masz nawet i to oczywiste wiedzy, żeby to wyłapać. Dlatego nie polecam za każdym razem tutoriali

Przyszła mi na myśl jeszcze jedna rzecz, ale byłoby to strasznie głupie z twojego pkt. pisania skoro uczysz się 

adnotacja @Entity? ale pochodzenia JPA. 

@Entity
public class ParkingEntity {

bo jeżeli to nie jest encja, to totalnie nie ma mowy o tym, żeby byla śledzona przez hibernate i wersjonowanie 

komentarz 19 marca 2022 przez Lulex Użytkownik (820 p.)
Encja jest śledzona, jeśli zmienię np liczbę slotów w parkingu przez update to wersja się podbija, jeśli zrobię update ale żadne pole się nie zmieni to jest w porządku.
komentarz 19 marca 2022 przez Wiciorny Ekspert (269,120 p.)

widzisz ale robiąc update ... na kolekcji, nie robisz update na parkingu jako obiektu... 

tutaj pojawia się problem tzw. tego co juz Ci pisałem brakuje Ci adnotacji CASCADE z odpowiednim zachowaniem, co ma się dziać na relacji kiedy zajdzie update. 
https://www.codejava.net/frameworks/hibernate/hibernate-many-to-many-association-with-extra-columns-in-join-table-example

// albo tak, albo analogicznie zaleznie od encji CarEntity... 
@OneToMany(mappedBy= "parking",cascade=CascadeType.ALL)
private Set<CarEntity> cars = new HashSet<>();

Oznacza CascadeType.ALLto, że trwałość będzie propagować (kaskadowo) wszystkie EntityManageroperacje ( PERSIST, REMOVE, REFRESH, MERGE, DETACH) do powiązanych jednostek.

komentarz 19 marca 2022 przez Lulex Użytkownik (820 p.)

Dzięki w ogóle za Twoją wytrwałość i chęć pomocy :D

Odkryłem jeszcze coś. Jeśli nie zrobię repository.save(entity) to nie wrzuca mi zmian do bazy, muszę dodać @Transactional nad metodą i wtedy już jest to zapisywane na bieżąco.

Bardzo dużo czytam i szukam info ale już mam śmietnik w głowie. Dodałem CascadType.ALL tak jak napisałeś, spróbowałem też dodawać to w entity. Dalej nic. 

 

widzisz ale robiąc update ... na kolekcji, nie robisz update na parkingu jako obiektu... 

To w jaki sposób mogę zrobić zmianę na parkingu, modyfikując kolekcję?

W ogóle hmmm... czy jeśli na chama próbuję zrobić coś w stylu:

parking.setCars( i wrzucam tutaj nowy set) to czy wersja powinna zrobić +1? 

 

Podobne pytania

0 głosów
0 odpowiedzi 131 wizyt
+1 głos
1 odpowiedź 132 wizyt
pytanie zadane 30 maja 2020 w JavaScript przez Greeenone Pasjonat (16,100 p.)
0 głosów
1 odpowiedź 297 wizyt
pytanie zadane 18 maja 2021 w PHP przez Bakkit Dyskutant (7,600 p.)

92,453 zapytań

141,262 odpowiedzi

319,088 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...