Otrzymuję następujący błąd hibernacji. Potrafię zidentyfikować funkcję, która powoduje problem. Niestety funkcja zawiera kilka wywołań DB. Nie mogę znaleźć linii, która powoduje problem, ponieważ hibernacja opróżnia sesję pod koniec transakcji. Poniższy błąd hibernacji wygląda na błąd ogólny. Nie wspomniano nawet, która fasola powoduje problem. Czy ktoś zna ten błąd hibernacji?
org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1
at org.hibernate.jdbc.BatchingBatcher.checkRowCount(BatchingBatcher.java:93)
at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:79)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:58)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:195)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:142)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:297)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:985)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:333)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:584)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransacti
onManager.java:500)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManag
er.java:473)
at org.springframework.transaction.interceptor.TransactionAspectSupport.doCommitTransactionAfterReturning(Transaction
AspectSupport.java:267)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)
Odpowiedzi:
Bez kodu i mapowań dla Twoich transakcji zbadanie problemu będzie prawie niemożliwe.
Aby jednak lepiej zrozumieć, co powoduje problem, spróbuj wykonać następujące czynności:
Mam nadzieję, że to pomoże.
źródło
Wystąpił ten sam wyjątek podczas usuwania rekordu według identyfikatora, który w ogóle nie istnieje. Więc sprawdź, czy rekord, który aktualizujesz / usuwasz, faktycznie istnieje w DB
źródło
Rozwiązanie: W pliku odwzorowania Hibernate dla właściwości id, jeśli używasz jakiejkolwiek klasy generatora, dla tej właściwości nie należy jawnie ustawiać wartości za pomocą metody ustawiającej.
Jeśli jawnie ustawisz wartość właściwości Id, spowoduje to powyższy błąd. Zaznacz to, aby uniknąć tego błędu. lub Pojawia się błąd, gdy wspomnisz w pliku mapowania generator pola = "natywny" lub "przyrostowy", aw BAZIE DANYCH mapowana tabela nie jest automatycznie_incremented Rozwiązanie: Przejdź do swojej BAZY DANYCH i zaktualizuj tabelę, aby ustawić auto_increment
źródło
Zdarzyło mi się to raz przez przypadek, kiedy przypisywałem określone identyfikatory do niektórych obiektów (testowanie), a potem próbowałem je zapisać w bazie danych. Problem polegał na tym, że w bazie danych istniała określona polityka dotycząca ustawiania identyfikatorów obiektów. Po prostu nie przypisuj identyfikatora, jeśli masz politykę na poziomie hibernacji.
źródło
W moim przypadku doszedłem do tego wyjątku w dwóch podobnych przypadkach:
@Transactional
miałem wywołanie innej usługi (z długim czasem odpowiedzi). Metoda aktualizuje niektóre właściwości jednostki (po metodzie jednostka nadal istnieje w bazie danych). Jeśli użytkownik dwukrotnie zażąda metody (za pierwszym razem uważa, że nie działa) przy wychodzeniu z metody transakcyjnej po raz drugi, Hibernate próbuje zaktualizować podmiot, który zmienił już swój stan od początku transakcji. Gdy Hibernacja wyszukuje encję w stanie i znalazła tę samą jednostkę, ale została już zmieniona przez pierwsze żądanie, zgłasza wyjątek, ponieważ nie może zaktualizować jednostki. To jak konflikt w GIT.Wniosek: w moim przypadku to nie był problem, który można znaleźć w kodzie. Ten wyjątek jest zgłaszany, gdy Hibernate stwierdzi, że jednostka pobrana z bazy danych jako pierwsza uległa zmianie podczas bieżącej transakcji , więc nie może jej opróżnić do bazy danych, ponieważ Hibernate nie wie, która wersja jednostki jest poprawna: ta bieżąca pobranie transakcji na początku; lub już zapisany w bazie danych.
Rozwiązanie: aby rozwiązać problem, będziesz musiał zagrać z Hibernate LockMode, aby znaleźć ten, który najlepiej odpowiada Twoim wymaganiom.
źródło
LockMode.READ
lubLockMode.OPTIMISTIC
.Właśnie napotkałem ten problem i dowiedziałem się, że usuwam rekord i próbuję go później zaktualizować w ramach transakcji Hibernate.
źródło
Może się to zdarzyć, gdy wyzwalacze wykonują dodatkowe zapytania DML (modyfikacja danych), które mają wpływ na liczbę wierszy. Moim rozwiązaniem było dodanie następującego kodu u góry mojego wyzwalacza:
źródło
Miałem ten sam problem. Kod działał w środowisku testowym. Ale to nie działało w środowisku przejściowym.
Problem polegał na tym, że tabela miała pojedynczy wpis dla każdego klucza podstawowego w testowej tabeli DB. Ale w pomostowej bazie danych było wiele wpisów dla tego samego klucza podstawowego. (Problem dotyczy przemieszczania bazy danych, tabela nie miała żadnych ograniczeń dotyczących klucza podstawowego, również było wiele wpisów).
Więc za każdym razem podczas operacji aktualizacji kończy się niepowodzeniem. Próbuje zaktualizować pojedynczy rekord i oczekuje, że liczba aktualizacji będzie wynosić 1. Ale ponieważ w tabeli były 3 rekordy dla tego samego klucza podstawowego, liczba aktualizacji wyników znajduje się na 3. Ponieważ oczekiwana liczba aktualizacji i rzeczywista liczba aktualizacji wyników nie zgadzają się , Zgłasza wyjątek i cofa się.
Po usunięciu wszystkich rekordów, które mają zduplikowany klucz podstawowy i dodałem ograniczenia klucza podstawowego. Działa dobrze.
rzeczywista liczba wierszy: 0 // oznacza brak rekordu do aktualizacji
update: 0 // oznacza brak rekordu, więc nie
oczekiwano żadnej aktualizacji : 1 // oznacza oczekiwany co najmniej 1 rekord z kluczem w tabeli db.
Tutaj problem polega na tym, że kwerenda próbująca zaktualizować rekord dla jakiegoś klucza, ale hibernacja nie znalazła żadnego rekordu z kluczem.
źródło
Jak mówi Julius , dzieje się tak, gdy następuje aktualizacja obiektu, którego elementy podrzędne są usuwane. (Prawdopodobnie dlatego, że istniała potrzeba aktualizacji całego Obiektu Ojca i czasami wolimy usunąć dzieci i ponownie wstawić je do Ojca (nowe, stare nie ma znaczenia) wraz z wszelkimi innymi aktualizacjami, które ojciec mógł mieć na dowolnym z jego inne zwykłe pola) Więc ... aby to zadziałało, usuń elementy podrzędne (w ramach transakcji), wywołując
childrenList.clear()
(nie zapętlaj elementów podrzędnych i usuwaj je z niektórymichildDAO.delete(childrenList.get(i).delete()))
i ustawieniami@OneToMany(cascade = CascadeType.XXX ,orphanRemoval=true)
po stronie Ojca Obiekt. Następnie zaktualizuj ojca (fatherDAO.update (father)). (Powtórz dla każdego obiektu ojca) Rezultat jest taki, że dzieciom zrywa się więź z ojcem, a następnie są usuwane jako sieroty przez ramy.źródło
Napotkałem ten problem, gdy mieliśmy relację jeden-wiele.
W pliku mapowania hibernacji hbm dla wzorca, dla obiektu z ustawionym ustawieniem typu, dodano
cascade="save-update"
i działało dobrze.Bez tego, domyślnie hibernacja próbuje zaktualizować nieistniejący rekord i zamiast tego wstawia.
źródło
Może się to również zdarzyć, gdy spróbujesz
UPDATE
użyć KLUCZA PODSTAWOWEGO .źródło
Mam ten sam problem i zweryfikowałem, że może to nastąpić z powodu klucza podstawowego automatycznego zwiększania. Aby rozwiązać ten problem, nie wstawiaj wartości automatycznego zwiększania do zestawu danych. Wstaw dane bez klucza podstawowego.
źródło
Innym sposobem na uzyskanie tego błędu jest sytuacja, gdy w kolekcji znajduje się pusty element.
źródło
dzieje się tak, gdy próbujesz usunąć ten sam obiekt, a następnie ponownie zaktualizować ten sam obiekt, użyj tego po usunięciu
session.clear ();
źródło
Mnie też się to przytrafiło, bo miałem swój id jako Long i otrzymywałem z widoku wartość 0, a kiedy próbowałem zapisać w bazie otrzymałem ten błąd, to naprawiłem go ustawiając id na null.
źródło
Napotkałem ten problem, gdy ręcznie rozpoczynałem i zatwierdzałem transakcje w ramach metody oznaczonej jako
@Transactional
. Rozwiązałem problem, wykrywając, czy aktywna transakcja już istniała.Następnie pozwoliłem Springowi zająć się zatwierdzeniem transakcji.
źródło
Dzieje się tak, gdy zadeklarowałeś zarządzany komponent Bean JSF jako
kiedy należy zadeklarować jako
Pozdrowienia;
źródło
Otrzymałem ten błąd, gdy próbowałem zaktualizować obiekt o identyfikatorze, którego nie ma w bazie danych. Powodem mojego błędu było to, że ręcznie przypisałem właściwość o nazwie „id” do reprezentacji obiektu w formacie JSON po stronie klienta, a następnie podczas deserializacji obiektu po stronie serwera ta właściwość „id” nadpisała zmienną instancji ( zwany także „id”), który miał wygenerować Hibernate. Dlatego uważaj na kolizje nazw, jeśli używasz Hibernate do generowania identyfikatorów.
źródło
Trafiłem też na to samo wyzwanie. W moim przypadku aktualizowałem obiekt, który nawet nie istniał, używając
hibernateTemplate
.Właściwie w mojej aplikacji otrzymywałem obiekt DB do aktualizacji. Aktualizując jego wartości, przez pomyłkę zaktualizowałem również jego identyfikator i poszedłem dalej, aby go zaktualizować i natrafiłem na wspomniany błąd.
Używam
hibernateTemplate
do operacji CRUD.źródło
Po przeczytaniu wszystkich odpowiedzi nie znalazłem nikogo, kto mógłby mówić o odwrotnym atrybucie hibernacji.
Moim zdaniem powinieneś również sprawdzić w swoich relacjach mapując, czy odwrotne słowo kluczowe jest odpowiednio ustawione. Odwrotność kluczowe jest tworzone w celu określenia, która strona jest właścicielem, który ma utrzymywać relację. Procedura aktualizacji i wstawiania różni się w zależności od tego atrybutu.
Załóżmy, że mamy dwie tabele:
Principal_table , middle_table
w relacji jeden do wielu . Klasy mapowania hiberntacji to odpowiednio Principal i Middle .
Więc klasa Principal ma zbiór obiektów Middle . Plik mapowania XML powinien wyglądać następująco:
Ponieważ inverse jest ustawione na „true”, oznacza to, że klasa „średnia” jest właścicielem relacji, więc klasa główna NIE ZAKTUALIZUJE relacji.
Tak więc procedurę aktualizacji można zaimplementować w następujący sposób:
U mnie to zadziałało, ale możesz zasugerować kilka edycji, aby ulepszyć rozwiązanie. W ten sposób wszyscy będziemy się uczyć.
źródło
W naszym przypadku w końcu odkryliśmy główną przyczynę StaleStateException.
W rzeczywistości usuwaliśmy wiersz dwukrotnie podczas jednej sesji hibernacji. Wcześniej używaliśmy ojdbc6 lib i w tej wersji było to w porządku.
Ale kiedy zaktualizowaliśmy do odjc7 lub ojdbc8, dwukrotne usuwanie rekordów było wyjątkiem. W naszym kodzie był błąd, który powodował dwukrotne usuwanie, ale nie było to widoczne w ojdbc6.
Udało nam się odtworzyć za pomocą tego fragmentu kodu:
Po pierwszym uruchomieniu hibernacja przechodzi i wprowadza zmiany w bazie danych. Podczas hibernacji drugiego rzutu porównuje obiekt sesji z rzeczywistym rekordem tabeli, ale nie może go znaleźć, stąd wyjątek.
źródło
Ten problem występuje głównie, gdy próbujemy zapisać lub zaktualizować obiekt, który został już pobrany do pamięci przez uruchomioną sesję. Jeśli pobrałeś obiekt z sesji i próbujesz zaktualizować bazę danych, może zostać zgłoszony ten wyjątek.
Użyłem session.evict (); aby najpierw usunąć pamięć podręczną przechowywaną w stanie hibernacji lub jeśli nie chcesz ryzykować utraty danych, lepiej wykonaj inny obiekt do przechowywania danych temp.
źródło
Problem z Hibernacją 5.4.1 i HHH-12878
Przed wersją Hibernate 5.4.1 optymistyczne wyjątki błędów blokowania (np.
StaleStateException
LubOptimisticLockException
) nie zawierały instrukcji niepowodzenia.Problem HHH-12878 został utworzony, aby ulepszyć Hibernację, tak aby podczas zgłaszania optymistycznego wyjątku blokującego
PreparedStatement
implementacja JDBC była również rejestrowana:Czas testowania
Najpierw zdefiniujemy
Post
byt, który definiuje@Version
właściwość, umożliwiając w ten sposób niejawny optymistyczny mechanizm blokujący :Włączymy przetwarzanie wsadowe JDBC przy użyciu następujących 3 właściwości konfiguracyjnych:
Mamy zamiar stworzyć 3
Post
podmioty:A Hibernate wykona wstawianie wsadowe JDBC:
Wiemy więc, że grupowanie JDBC działa dobrze.
Teraz powtórzmy optymistyczny problem z blokowaniem:
Pierwsza transakcja wybiera wszystkie
Post
jednostki i modyfikuje pliktitle
właściwości.Jednak zanim pierwsze
EntityManager
zostanie opróżnione, wykonamy drugie przejście za pomocąexecuteSync
metody.Druga transakcja modyfikuje pierwszą
Post
, więc jej wartośćversion
zostanie zwiększona:Teraz, gdy pierwsza transakcja spróbuje opróżnić
EntityManager
, otrzymamyOptimisticLockException
:Tak więc, aby skorzystać z tego ulepszenia, musisz dokonać aktualizacji do wersji Hibernate 5.4.1 lub nowszej.
źródło
Dzieje się tak, jeśli zmienisz coś w zestawie danych za pomocą natywnego zapytania sql, ale utrwalony obiekt dla tego samego zestawu danych jest obecny w pamięci podręcznej sesji. Użyj session.evict (yourObject);
źródło
Hibernacja buforuje obiekty z sesji. Jeśli obiekt jest dostępny i modyfikowany przez więcej niż 1 użytkownika,
org.hibernate.StaleStateException
może zostać wyrzucony. Można to rozwiązać za pomocą metody scalania / odświeżania encji przed zapisaniem lub użyciem blokady. Więcej informacji: http://java-fp.blogspot.lt/2011/09/orghibernatestalestateexception-batch.htmlźródło
Jeden z przypadków
źródło
Miałem do czynienia z tym wyjątkiem i hibernacja działała dobrze. Próbowałem ręcznie wstawić jeden rekord za pomocą pgAdmin, tutaj problem stał się jasny. Zapytanie SQL wstawiające zwraca 0 wstawiania. i istnieje funkcja wyzwalająca, która powoduje ten problem, ponieważ zwraca wartość null. więc muszę tylko ustawić go na powrót nowy. iw końcu rozwiązałem problem.
mam nadzieję, że pomoże to każdemu ciału.
źródło
Otrzymałem ten błąd, ponieważ omyłkowo zamapowałem
ID
kolumnę za pomocąId(x => x.Id, "id").GeneratedBy.**Assigned**();
Problem rozwiązany za pomocą
Id(x => x.Id, "id").GeneratedBy.**Identity**();
źródło
Dzieje się tak, ponieważ brakuje mi deklaracji identyfikatora w klasie fasoli.
źródło
W moim przypadku wystąpił problem z bazą danych, ponieważ jeden z przechowywanych procesów zużywał cały procesor, powodując wysokie czasy odpowiedzi bazy danych. Po zabiciu problem został rozwiązany.
źródło