2013-05-25 29 views
27

Mam błąd, który wygląda tak:Nie można zainicjować serwera proxy - nie Session

Nie można zainicjować serwera proxy - nie Session

pracuję z Java, hibernacji i wiosną . Ten błąd pojawia się podczas próby wygenerowania dokumentu PDF i postępuję zgodnie z następnymi krokami, aby wygenerować go w locie i przechowywać w bazie danych.

  1. Wysłałem żądanie do aplikacji za pomocą metody POST. Generuje plik PDF w locie i wyświetla się użytkownikowi.

  2. Zaraz po tym wniosku wysyłam inny, ale za pomocą ajax żądanie. Spowoduje to wygenerowanie tego samego pliku PDF, ale zapisze go w DB.

Błąd pokazuje, że zapytanie nie mogło zostać wykonane z powodu błędu "nie można zainicjować proxy - brak sesji".

Czy jest coś, co robię źle, wywołując te same metody dwa razy z tej samej sesji użytkownika? Czy to możliwe, że sesja zostanie zamknięta przed zakończeniem obu wniosków?

Mam nadzieję, że ktoś może mi pomóc zrozumieć, co się dzieje.

+0

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

+0

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ę. –

+0

Problem z hibernacją. Pokaż nam kod wywołania Ajax, abyśmy mogli Ci pomóc. – Jukka

Odpowiedz

67

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.

+0

Im za pomocą sprężyny. Więc zgodnie z twoją odpowiedzią pierwsze żądanie działa z informacjami pobranymi z bazy danych za pomocą hibernacji. Następnie przychodzi drugie żądanie i próbuje uzyskać dostęp do tych samych danych, które powodują niepowodzenie zapytania, ponieważ pierwsze żądanie zamknęło sesję hibernacji, zanim drugie żądanie zakończy swoje zadanie. Czy mam rację? –

+0

Masz to. Te same dane, o których wspominasz, to jednostki, które istnieją w twojej sesji użytkownika (HttpSession). Podczas drugiego żądania hibernacja próbuje wypełnić obiekt proxy (który jest imitacją rzeczywistego obiektu) informacjami z bazy danych. Przed próbą wykonania zapytań, które będą pobierać dane, hibernate próbuje znaleźć obiekt sesji hibernacji skojarzony z tym obiektem proxy. Ale obiekt proxy nie jest powiązany z sesją hibernacji. Jednostka ojca obiektu proxy została odłączona od sesji po zakończeniu pierwszego żądania. – nakosspy

+0

edytowane z dodatkowymi informacjami na temat cykli przetwarzania żądań. – nakosspy

Powiązane problemy