Mam dwa obiekty użytkownika i podczas próby zapisania obiektu za pomocą
session.save(userObj);
Otrzymuję następujący błąd:
Caused by: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session:
[com.pojo.rtrequests.User#com.pojo.rtrequests.User@d079b40b]
Sesję tworzę za pomocą
BaseHibernateDAO dao = new BaseHibernateDAO();
rtsession = dao.getSession(userData.getRegion(),
BaseHibernateDAO.RTREQUESTS_DATABASE_NAME);
rttrans = rtsession.beginTransaction();
rttrans.begin();
rtsession.save(userObj1);
rtsession.save(userObj2);
rtsession.flush();
rttrans.commit();
rtsession.close(); // in finally block
Próbowałem też zrobić to session.clear()
przed zapisaniem, nadal bez powodzenia.
Po raz pierwszy otrzymuję obiekt sesji, gdy przychodzi żądanie użytkownika, więc otrzymuję dlaczego mówi, że obiekt jest obecny w sesji.
Jakieś sugestie?
Odpowiedzi:
Miałem ten błąd wiele razy i może być dość trudno wytropić ...
Zasadniczo hibernacja mówi, że masz dwa obiekty, które mają ten sam identyfikator (ten sam klucz podstawowy), ale nie są tym samym obiektem.
Proponuję rozbić kod, tj. Zakomentować bity, aż błąd zniknie, a następnie wstawić kod z powrotem, aż wróci i powinieneś znaleźć błąd.
Najczęściej dzieje się to poprzez składowanie kaskadowe, gdzie między obiektami A i B jest zapis kaskadowy, ale obiekt B został już powiązany z sesją, ale nie znajduje się w tej samej instancji B, co obiekt w A.
Jakiego generatora kluczy podstawowych używasz?
Pytam o to, że ten błąd jest związany ze sposobem, w jaki mówisz do hibernacji, aby ustalić trwały stan obiektu (tj. Czy obiekt jest trwały, czy nie). Błąd może występować, ponieważ hibernacja próbuje utrwalić obiekt, który jest już trwały. W rzeczywistości, jeśli użyjesz zapisania, hibernacja spróbuje zachować ten obiekt, a być może istnieje już obiekt z tym samym kluczem podstawowym skojarzonym z sesją.
Przykład
Zakładając, że masz obiekt klasy hibernacji dla tabeli z 10 wierszami na podstawie kombinacji klawiszy podstawowych (kolumna 1 i kolumna 2). Teraz w pewnym momencie usunąłeś 5 wierszy z tabeli. Teraz, jeśli spróbujesz ponownie dodać te same 10 wierszy, podczas gdy hibernacja próbuje zachować obiekty w bazie danych, 5 wierszy, które zostały już usunięte, zostanie dodanych bez błędów. Teraz pozostałe 5 wierszy, które już istnieją, zgłosi ten wyjątek.
Więc prostym podejściem byłoby sprawdzenie, czy zaktualizowałeś / usunąłeś jakąkolwiek wartość w tabeli, która jest częścią czegoś, a później czy próbujesz ponownie wstawić te same obiekty
źródło
To tylko jeden punkt, w którym hibernacja stwarza więcej problemów niż rozwiązuje. W moim przypadku jest wiele obiektów o tym samym identyfikatorze 0, ponieważ są nowe i go nie mają. Baza danych je generuje. Gdzieś przeczytałem, że 0 sygnałów nie było ustawione. Intuicyjnym sposobem ich utrwalenia jest iterowanie po nich i mówienie o hibernacji, aby zapisać obiekty. Ale nie możesz tego zrobić - „Oczywiście powinieneś wiedzieć, że hibernacja działa w ten i ten sposób, dlatego musisz…” Więc teraz mogę spróbować zmienić ID na długie zamiast na długie i sprawdzić, czy to działa. Ostatecznie łatwiej jest to zrobić za pomocą prostego mapera, ponieważ hibernacja jest tylko dodatkowym nieprzejrzystym obciążeniem. Inny przykład: próba odczytania parametrów z jednej bazy danych i utrwalenia ich w innej wymusza wykonanie prawie całej pracy ręcznie.
źródło
USe
session.evict(object);
Funkcjaevict()
metody służy do usuwania instancji z pamięci podręcznej sesji. Tak więc przy pierwszym zapisaniu obiektu zapisz obiekt, wywołującsession.save(object)
metodę przed wykluczeniem obiektu z pamięci podręcznej. W ten sam sposób aktualizuj obiekt przez wywołaniesession.saveOrUpdate(object)
lubsession.update(object)
przed wywołaniem evict ().źródło
Może się to zdarzyć, gdy użyłeś tego samego obiektu sesji do odczytu i zapisu. W jaki sposób? Powiedzmy, że utworzyłeś jedną sesję. Odczytujesz rekord z tabeli pracowników z kluczem podstawowym Emp_id = 101 Teraz zmodyfikowałeś rekord w Javie. Zamierzasz zapisać rekord pracownika w bazie danych. nigdzie nie zamknęliśmy sesji. Ponieważ obiekt, który został odczytany, również pozostaje w sesji. Koliduje z przedmiotem, który chcemy napisać. Stąd ten błąd.
źródło
Jak ktoś już wskazał powyżej, napotkałem ten problem, gdy miałem
cascade=all
na obu końcachone-to-many
relacji, więc załóżmy, że A -> B (jeden do wielu z A i wiele do jednego z B) i aktualizowałem instancję B w A, a następnie wywołanie saveOrUpdate (A), spowodowało to cykliczne żądanie składowania, tj. Zapis A wyzwala zapis B, który wyzwala zapis A ... iw trzecim przypadku, gdy jednostka (A) była próbowana być dodany do sessionPersistenceContext, zgłoszony został wyjątek duplicateObject.Mogłem to rozwiązać, usuwając kaskadę z jednego końca.
źródło
Możesz użyć
session.merge(obj)
, jeśli robisz składowanie z różnymi sesjami z tym samym trwałym obiektem identyfikatora.Udało się, wcześniej miałem ten sam problem.
źródło
Natknąłem się również na ten problem i ciężko mi było znaleźć błąd.
Problem, który miałem, był następujący:
Obiekt został odczytany przez Dao podczas innej sesji hibernacji.
Aby uniknąć tego wyjątku, po prostu ponownie przeczytaj obiekt za pomocą dao, który później zapisze / zaktualizuje ten obiekt.
więc:
Mam nadzieję, że zaoszczędzi to niektórym ludziom dużo czasu!
źródło
Natknąłem się na ten problem przez:
Rozwiązałem to, opróżniając wyniki po usunięciu i czyszcząc pamięć podręczną przed zapisaniem nowego obiektu
źródło
Ten problem pojawia się, gdy aktualizujemy ten sam obiekt sesji, którego użyliśmy do pobrania obiektu z bazy danych.
Możesz użyć metody scalania hibernacji zamiast metody aktualizacji.
np. Najpierw użyj session.get (), a następnie możesz użyć session.merge (obiekt). Ta metoda nie spowoduje żadnego problemu. Możemy również użyć metody merge () do aktualizacji obiektu w bazie danych.
źródło
Pobierz obiekt w ramach sesji, tutaj przykład:
źródło
Czy twoje mapowania identyfikatorów są prawidłowe? Jeśli baza danych jest odpowiedzialna za tworzenie Id za pomocą identyfikatora, musisz zmapować swój obiekt użytkownika do tego.
źródło
Napotkałem ten problem przy usuwaniu obiektu, ani eksmisja, ani czyszczenie nie pomogły.
źródło
przed pozycją, w której zaczynają się powtarzające się obiekty, należy zamknąć sesję, a następnie rozpocząć nową sesję
w ten sposób w jednej sesji nie ma więcej niż jednej jednostki, która ma ten sam identyfikator.
źródło
Spóźniony na imprezę, ale może pomóc przyszłym użytkownikom -
Mam ten problem, gdy wybieram rekord za pomocą
getsession()
i ponownie aktualizuję inny rekord z tym samym identyfikatorem przy użyciu tej samej sesji powoduje problem. Dodano kod poniżej.Nigdy nie powinno się tego robić. Rozwiązaniem jest wykluczenie sesji przed aktualizacją lub zmiana logiki biznesowej.
źródło
Sprawdź, czy nie zapomniałeś wstawić @GenerateValue dla kolumny @Id. Miałem ten sam problem z wieloma do wielu związkami między filmem a gatunkiem. Program wyrzucił błąd Hibernate: org.hibernate.NonUniqueObjectException: inny obiekt o tej samej wartości identyfikatora był już powiązany z błędem sesji. Później dowiedziałem się, że muszę się tylko upewnić, że w metodzie GenreId get masz @GenerateValue.
źródło
po prostu sprawdź identyfikator, czy przyjmuje wartość null lub 0
w dodawaniu lub aktualizowaniu, gdzie zawartość jest ustawiana z formularza na Pojo
źródło
Jestem nowy w NHibernate i mój problem polegał na tym, że użyłem innej sesji do odpytania o mój obiekt niż do zapisania go. Więc sesja zapisu nie wiedziała o obiekcie.
Wydaje się to oczywiste, ale czytając poprzednie odpowiedzi szukałem wszędzie 2 obiektów, a nie 2 sesji.
źródło
@GeneratedValue (strategy = GenerationType.IDENTITY), dodanie tej adnotacji do właściwości klucza podstawowego w komponencie bean encji powinno rozwiązać ten problem.
źródło
Rozwiązałem ten problem.
Właściwie to się dzieje, ponieważ zapomnieliśmy o implementacji właściwości PK typu generatora w klasie bean. Więc zrób to dowolny typ, taki jak
kiedy utrwalamy obiekty z fasoli, każdy obiekt uzyskał ten sam identyfikator, więc pierwszy obiekt jest zapisywany, gdy inny obiekt ma być utrwalony, to HIB FW przez ten typ
Exception: org.hibernate.NonUniqueObjectException:
innego obiektu o tej samej wartości identyfikatora był już powiązany z sesją.źródło
Problem występuje, ponieważ w tej samej sesji hibernacji próbujesz zapisać dwa obiekty o tym samym identyfikatorze.Istnieją dwa rozwiązania: -
Dzieje się tak, ponieważ nie skonfigurowałeś poprawnie pliku mapping.xml dla pól id, jak poniżej: -
Przeciąż metodę getsession, aby zaakceptować parametr, taki jak isSessionClear, i wyczyść sesję przed zwróceniem bieżącej sesji, jak poniżej
Spowoduje to wyczyszczenie istniejących obiektów sesji, a nawet jeśli hibernacja nie wygeneruje unikalnego identyfikatora, zakładając, że poprawnie skonfigurowałeś bazę danych dla klucza podstawowego przy użyciu czegoś takiego jak Auto_Increment, powinno to działać dla Ciebie.
źródło
Miałem podobny problem. W moim przypadku zapomniałem ustawić
increment_by
wartość w bazie danych na taką samą, jak ta używana przezcache_size
iallocationSize
. (Strzałki wskazują wymienione atrybuty)SQL:
Jawa:
źródło
W przeciwieństwie do tego, co powiedział wbdarby , może się to zdarzyć nawet, gdy obiekt jest pobierany przez przekazanie identyfikatora obiektu do HQL. W przypadku próby zmodyfikowania pól obiektu i zapisania go z powrotem do DB (modyfikacja może być wstawieniem, usunięciem lub aktualizacją) w tej samej sesji , pojawi się ten błąd. Spróbuj wyczyścić sesję hibernacji przed zapisaniem zmodyfikowanego obiektu lub utwórz zupełnie nową sesję.
Mam nadzieję, że pomogłem ;-)
źródło
Mam ten sam błąd co przy wymianie mojego zestawu na nowy otrzymany od Jacksona.
Aby rozwiązać ten problem, zachowuję istniejący zestaw, usuwam ze starego zestawu nieznany element do nowej listy za pomocą
retainAll
. Następnie dodaję nowe zaddAll
.Nie ma potrzeby posiadania sesji i manipulowania nią.
źródło
Spróbuj tego. Poniższy działał dla mnie!
W
hbm.xml
plikuMusimy ustawić
dynamic-update
atrybut tagu klasy natrue
:Ustaw atrybut class znacznika generatora w unikalnej kolumnie na
identity
:Uwaga: ustaw unikatową kolumnę
identity
zamiastassigned
.źródło
Inną rzeczą, która zadziałała, było ustawienie zmiennej instancji Long zamiast long
Miałem długi id zmiennej klucza głównego; zmieniając go na Long id; pracował
Wszystkiego najlepszego
źródło
Zawsze możesz wykonać rzut sesyjny. Flush zsynchronizuje stan wszystkich twoich obiektów w sesji (proszę, ktoś mnie poprawi, jeśli się mylę) i być może w niektórych przypadkach rozwiąże twój problem.
Wdrożenie własnych równych sobie i hashcode również może Ci pomóc.
źródło
Możesz sprawdzić ustawienia kaskady. Przyczyną mogą być ustawienia kaskady w Twoich modelach. Usunąłem Ustawienia kaskadowe (zasadniczo nie zezwalam na wstawianie / aktualizacje kaskadowe) i to rozwiązało mój problem
źródło
Znalazłem również ten błąd. Udało mi się upewnić, że klucz podstawowy (który jest generowany automatycznie) nie jest PDT (tj. Long, int, ect.), Ale obiektem (tj. Long, Integer itp.)
Kiedy tworzysz obiekt, aby go zapisać, upewnij się, że podajesz wartość null, a nie 0.
źródło
czy to pomaga?
źródło
Rozwiązałem podobny problem, taki jak ten:
źródło