Twoim problemem jest to, że sesja hibernacji trwa tylko jedno żądanie. Otwiera się na początku żądania i zamyka na końcu. Zgadłeś odpowiedź: Sesja hibernacji zostaje zamknięta przed zakończeniem obu wniosków.
Dokładnie to, co się dzieje? Twoje obiekty encji są aktywne podczas obu żądań. W jaki sposób? Są one przechowywane w sesji HTTP (co jest inną rzeczą nazywaną sesją) Nie podajesz zbyt wielu informacji o strukturze, z której korzystasz, więc nie mogę podać więcej szczegółów, ale pewne jest, że struktura, której używasz w jakiś sposób utrzymuje twoje jednostki w sesji HTTP. W ten sposób ramy ułatwiają pracę z tymi samymi obiektami dla więcej niż jednego żądania.
Po rozpoczęciu przetwarzania drugiego żądania kod próbuje uzyskać dostęp do jakiejś encji (zwykle elementu kolekcji), która jest leniwie inicjowana przez hibernację. Encja nie jest dołączona do sesji hibernacji, więc hibernate nie może zainicjować proxy hibernacji przed jego odczytaniem. Powinieneś otworzyć sesję i ponownie dołączyć do niej swój podmiot na początku przetwarzania żądania ajax.
EDIT:
postaram się dać krótki opis tego, co dzieje się za sceną. Wszystkie struktury WWW java mają jedną lub więcej serwletów, które obsługują żądania. Serwlet obsługuje każde żądanie (HttpRequest), tworząc nowy wątek, który ostatecznie wygeneruje odpowiedź (HttpResponse). Metoda, która przetwarza każde żądanie, jest wykonywana wewnątrz tego wątku.
Na początku przetwarzania żądania aplikacja powinna przydzielić zasoby potrzebne do przetwarzania (transakcja, sesja hibernacji itp.). Pod koniec cyklu przetwarzania zasoby są zwalniane (transakcja jest zatwierdzana, sesja hibernacji jest zamknięta, wydawane są połączenia JDBC itp.). Cykl życia tych zasobów może być zarządzany przez twoją strukturę lub może być wykonywany przez twój kod.
Aby obsłużyć stan aplikacji w protokole bezstanowym jako HTTP, mamy obiekt HttpSession. My (lub frameworki) umieszczamy na HttpSession informacje, które pozostają istotne dla różnych cykli żądań tego samego klienta.
Podczas przetwarzania pierwszego żądania, hibernacja odczytuje (leniwie) encję z bazy danych. Z powodu leniwego inicjowania niektóre części struktury tego obiektu są obiektami proxy typu hibernacja. Te obiekty są powiązane z sesją hibernacji, która je utworzyła.
Framework odnajduje obiekt z poprzedniego żądania w obiekcie HttpSession podczas próby przetworzenia drugiego żądania. Następnie próbuje uzyskać dostęp do właściwości z elementu podrzędnego, który został zainicjowany leniwie, a teraz jest obiektem proxy typu hibernacja. Obiekt proxy hibernacji jest imitacją rzeczywistego obiektu, który poprosi o sesję hibernacji, aby wypełnić go informacjami z bazy danych, gdy ktoś spróbuje uzyskać dostęp do jednej z jego właściwości. To właśnie próbuje wykonać twój serwer proxy hibernacji. Ale jego sesja została zamknięta pod koniec przetwarzania poprzedniego żądania, więc teraz nie ma sesji hibernacji, która mogłaby zostać użyta do uwodnienia (wypełniona prawdziwymi informacjami).
Należy zauważyć, że możliwe jest, że sesja hibernacji została już otwarta na początku drugiego żądania, ale nie jest ona świadoma obiektu zawierającego obiekt proxy, ponieważ ta jednostka była odczytywana przez inną sesję hibernacji. Powinieneś ponownie dołączyć encję do nowej sesji hibernacji.
Istnieje wiele dyskusji na temat ponownego dołączenia odłączonego obiektu, ale najprostszym rozwiązaniem jest teraz session.update(entity)
.
Mam nadzieję, że to pomaga.
Pomijając błąd, po co wykonywać dwa wyraźne wywołania, aby utworzyć plik PDF? Zrób to raz, utrzymuj go, a następnie pobierz go z bazy danych. – Makoto
Kiedy pisałem pytanie, myślałem tak samo, jak sugerujesz. Ale chciałem, żeby ktoś z nieco większym doświadczeniem potwierdził to samo. I tylko po to, by był bardziej użyteczny ... Czy możesz wyjaśnić, dlaczego w tym scenariuszu "nie można zainicjować proxy - brak sesji"? z góry dziękuję. –
Problem z hibernacją. Pokaż nam kod wywołania Ajax, abyśmy mogli Ci pomóc. – Jukka