Pytanie jest w tytule. Poniżej opisałem tylko niektóre z moich przemyśleń i spostrzeżeń.
Kiedy miałem bardzo prosty model domeny (3 tabele bez żadnych relacji), wszystkie moje encje NIE implementowały Serializable.
Ale kiedy model domeny stał się bardziej złożony, otrzymałem RuntimeException, który powiedział, że jedna z moich jednostek nie zaimplementowała Serializable.
Używam Hibernate jako implementacji JPA.
Zastanawiam się:
- Czy jest to wymóg / zachowanie specyficzne dla dostawcy?
- Co dzieje się z moimi jednostkami możliwymi do serializacji? Czy powinny być możliwe do serializacji w celu przechowywania lub przenoszenia?
- W którym momencie konieczne jest umożliwienie serializacji mojej jednostki?
Serializable
to dwie różne koncepcje.Zgodnie ze specyfikacją JPA:
„JSR 220: Enterprise JavaBeansTM, wersja 3.0 Java Persistence API wersja 3.0, ostateczne wydanie 2 maja 2006”
źródło
Serializable
mógłby być w tym pomocny i bardziej konsekwentny w kontekście wytrwałości niżCloneable
na przykład.Potrzebujesz swoich encji,
Serializable
jeśli chcesz przesłać je przez sieć (serializować je do innej reprezentacji), przechowywać je w sesji http (która z kolei jest serializowana na dysk twardy przez kontener serwletów) itp.Tylko ze względu na wytrwałość
Serializable
nie jest potrzebny, przynajmniej w przypadku Hibernate. Ale najlepiej jest je robićSerializable
.źródło
Zgodnie z dokumentacją hibernacji , używając adnotacji @JoinColumn:
źródło
Jako uzupełnienie miłej odpowiedzi Conora, który odniósł się do specyfikacji JSR-317. Zazwyczaj projekty EAR składają się z modułu EJB z EJB udostępnionymi przez zdalny interfejs. W tym jednym przypadku konieczne jest umożliwienie serializacji komponentów bean encji, ponieważ są one zagregowane w zdalnym komponencie EJB i zbudowane tak, aby można je było łączyć za pośrednictwem sieci.
Projekt wojenny JEE6 bez CDI: może zawierać EJB Lite wspierany przez nie-serializowalne jednostki JPA.
Projekt wojenny JEE6 z CDI: Fasole, które używają zakresu sesji, aplikacji lub konwersacji, muszą być serializowalne, ale komponenty bean używające zakresu żądania nie muszą być serializowane. W ten sposób bazowa fasola encji JPA - jeśli w ogóle - miałaby tę samą semantykę.
źródło
Jeśli mówimy tylko o wytrwałości,
Serializable
nie jest to potrzebne, ale najlepszą praktyką jest tworzenie bytówSerializable
.Jeśli eksponujemy
domain
/entities
obiekty bezpośrednio wystawiane na warstwę prezentacji, to zamiast używaćDTO
, w takim przypadku musimy zaimplementowaćSerializable
. Te obiekty domeny mogą być przechowywane wHTTPSession
celu buforowania / optymalizacji. Sesja http może być serializowana lub klastrowana. Jest to również wymagane do przesyłania danych międzyJVM
okolicznościami.Kiedy używamy
DTO
do oddzielenia warstwy trwałości od warstwy usług, oznaczanie obiektów domeny jakoSerializable
nieproduktywne i naruszałoby „encapsulation
”. Wtedy staje się anty-wzorcem.Identyfikatory złożone
Klasa klucza podstawowego musi być możliwa do serializacji.
Modele POJO
Jeśli instancja jednostki ma być używana zdalnie jako obiekt odłączony, klasa jednostki musi implementować
Serializable
interfejs.Pamięć podręczna
Ponadto, jeśli wdrażasz
clustered
drugi poziom,cache
Twoje encje muszą byćserializable
. Identyfikator musi być,Serializable
ponieważ jest to wymóg JPA, ponieważidentifier
może być używany jako klucz dla wpisu pamięci podręcznej drugiego poziomu.A kiedy serializujemy jednostki, upewnij się, że podajesz jawny
serialVersionUID
modyfikator dostępu prywatnego. Ponieważ jeśliserializable
klasa nie deklaruje jawnie aserialVersionUID
, wówczas środowisko wykonawcze serializacji obliczyserialVersionUID
wartość domyślną dla tej klasy na podstawie różnych aspektów tej klasy, zgodnie z opisem w specyfikacji serializacji obiektów Java (TM).serialVersionUID
Obliczenia domyślne są bardzo wrażliwe na szczegóły klasy, które mogą się różnić w zależności od implementacji kompilatora i mogą w związku z tym powodować nieoczekiwaneInvalidClassExceptions
podczas deserializacji.źródło
Uważam, że twój problem jest związany z posiadaniem pola typu złożonego (klasy), które nie jest opatrzone adnotacjami. W takich przypadkach domyślną obsługą będzie przechowywanie obiektu w jego serializowanej postaci w bazie danych (co prawdopodobnie nie jest tym, co chciałeś zrobić) Przykład:
W powyższym przypadku CustomerData zostanie zapisane w polu tablicy bajtów w bazie danych w postaci serializowanej.
źródło
Specyfikacja JPA
Zgodnie ze specyfikacją JPA jednostka powinna być wdrażana
Serializable
tylko wtedy, gdy musi zostać przekazana z jednej maszyny JVM do drugiej lub jeśli jednostka jest używana przez Stateful Session Bean, który musi zostać pasywowany przez kontener EJB.Hibernować
Hibernacja wymaga tylko, aby atrybuty jednostki były
Serializable
, ale nie samej jednostki.Jednak implementując specyfikację JPA, wszystkie wymagania JPA dotyczące
Serializable
podmiotów dotyczą również Hibernate.Kocur
Według Tomcat documantation , te
HttpSession
atrybuty muszą być równieżSerializable
:Tak więc, jeśli jednostka jest przechowywana w formacie
HttpSession
, powinna zaimplementowaćSerializable
.źródło
Klasy muszą implementować Serializable, jeśli chcesz je serializować. Nie jest to bezpośrednio związane z JPA, a specyfikacja JPA nie wymaga, aby jednostki były serializowane. Jeśli Hibernate naprawdę narzeka na to, przypuszczam, że jest to błąd Hibernacji, ale przypuszczam, że bezpośrednio lub pośrednio robisz coś innego z bytami, które wymagają, aby były możliwe do serializacji.
źródło
Zapoznaj się z http://www.adam-bien.com/roller/abien/entry/do_jpa_entities_have_to, gdzie jest napisane: Implementacja java.io.Serializable jest po prostu wymagana do przesyłania danych przez IIOP lub JRMP (RMI) między instancjami JVM. W przypadku czystej aplikacji internetowej obiekty domeny są czasami przechowywane w HTTPSession w celu buforowania / optymalizacji. Sesja http może być serializowana (pasywacja) lub klastrowana. W obu przypadkach cała zawartość musi być serializowalna.
źródło
zdalne trafienie przy użyciu postman, ajax lub angular js itp ..... może spowodować cykl powtarzania z wyjątkiem StackOverflow z Jackson szybciejXml. Dlatego lepiej jest użyć serializatora.
źródło
Wdrożenie ehcache z magazynem dyskowym jako pamięcią podręczną drugiego poziomu (tj. Przy użyciu
@Cacheable
adnotacji na jednostce lub metodzie repozytorium / usługi) wymaga Serializable, w przeciwnym razie pamięć podręczna nie powiedzie się (NotSerializableException
), aby zapisać jednostkę do pamięci podręcznej dysku.źródło
Jest to również błąd, który pojawia się, gdy przekazujesz niepoprawnie wpisany identyfikator jako drugi parametr do czegoś takiego jak em.find () (tj. Przekazując samą jednostkę zamiast jej identyfikatora). Nie uważam jeszcze za konieczne, aby faktycznie zadeklarować jednostki JPA jako możliwe do serializacji - nie jest to naprawdę konieczne, chyba że używasz referencedColumnName zgodnie z opisem amana.
źródło
gdy jednostki JPA są używane jako parametry lub zwracają wartości przez zdalne operacje EJB
źródło