# java.io.NotSerializableException für domain Objekte - Design Problem?



## lieschen89 (4. Sep 2013)

Hi,

ich habe meine Beans Serializable gemacht. Das Problem im Moment ist denke ich, dass ich in meinem Beans neben int und String Variablen auch meine Domain-Objekte verwende. 

Am Beispiel Auto:
In meiner AutoBean habe ich als Variable resultList eine Liste von Autos (List<..domain.Auto>) oder z.B. auch eine Variable marke vom Typ ...domain.Marke.

Diese Domain Objekte sind nicht Serializable. Nun bekomme ich den Fehler:


```
SCHWERWIEGEND: IOException while loading persisted sessions: java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: ..domain.Auto
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: ..domain.Auto
```

Wenn ich richtig liege, dann kommt dass daher, da versucht wird alle in meiner Bean referenzierte Objekte wegen der Serialisierung zu speichern.

*Frage:*

Da ich aber noch keinen serialisierten Domain-Objekte gesehen habe, stellt sich mir die Frage ob das oben stehende mit den Refenzierten Domain-Objekten in den Beans ein 'schhlechtes Design oder Architektur' ist. Mach man das nicht so?

Wie soll ich denn sonst die Daten da hin und her übertragen?


Das mit der Marke könnte ich ja umgehen, indem ich einfach nur die id speicher als int. 
(Aber selbst das finde ich umständlich für die jsf-Seiten, weil wenn ich dann die Marke eines Autos ausgeben möchte, bekomme ich immer nur die Id aus der Bean und muss mir den Namen immer erst
umständlich besorgen. Das finde ich eigenlich schon unschön. Vor allem weil in den Domain Objekten, wo das Mapping zur DB stattfindet, da auch ganz normal die Objekte und nicht irgendwelche ids drinstehen.)


----------



## sence (4. Sep 2013)

Wenn du hibernate verwendest, müssen die Objekte schon serialisierend implementierent aufgebaut sein.

Eine durch die Referenzierung von Objekten ausgestattene Bean muss vollständig serialisiebar sein, damit der Server den States schreiben kann.
Wird Session Replikation verwendet, würdest du spätestens dann an das Problem erneut stoßen

Chapter 2. Mapping Entities

VG


----------



## lieschen89 (4. Sep 2013)

ok.
Aber das zieht sich ja dann komplett durch dass die Controller und Services auch serialisierbar gemacht werde müssen oder nicht? Und da die Services die Daos verwenden die dann auch? Und damit sind dann alle Klassen meiner Anwendung serialisierbar? Das passt dann?
Ich mein iwie ist mir schon klar, dass ich die ganzen Referenzen brauche, aber iwie kommt mir das komisch vor und bevor ich da totalen Mist hin programmier wollte ich sicher gehen.


Vor allem bekomme ich jetzt immer:


```
java.io.NotSerializableException: org.springframework.orm.hibernate3.HibernateTemplate
```

Den einzigen Lösungsvorschlag den ich gefunden habe, war das hibernateTemplate als @Transient zu annotieren. Allerdings hilft das nichts.


----------



## Nogothrim (5. Sep 2013)

Ist es denn überhaupt gewollt, ganze Sessions zu persistieren? Sieht so aus, als wenn der Fehler dabei auftritt, z.B. beim Server runterfahren.


----------



## lieschen89 (5. Sep 2013)

Der Fehler tritt immer beim Starten vo Tomcat auf.

Ja, wie gesagt, denke auch nicht dass ich das brauche. Der größte Teil ist einfach ne Website mit festen Daten. 
Das einzige wo Logik dahinter steckt ist ne kleine Suche und ne Art Berechnung (ein Formular mit Eingabefeld, Button und Ausgabe). Beides Mal wird nach dem Klick auf einen Button das Ergebnis angezeigt und fertig. Wenn man wieder weg navigiert sind die Daten weg (Request Scope?).
Also denke ich nicht dass ich da irgend etwas speichern muss/sollte (?)


----------



## sence (6. Sep 2013)

für die kleine Anwendung, brauchst du es dann nicht, das ist richtig.
Verwendest du  irgendwann Session Replikation, hibernate, wirst du dann darauf ausbauen müssen.

bin zu Begin von einer größeren Anwendung ausgegangen.
requestscope: für einmal einmal aktitionen.
viewscope: alle States der Bean werden beibehalten, solange der User auf der View ist und nicht weg navigiert.


----------



## lieschen89 (6. Sep 2013)

Session Replikation? Also ich denke nicht, zumindest nicht gewollt. Wüsste auch gar nicht wie das geht.



> für die kleine Anwendung, brauchst du es dann nicht, das ist richtig.



Das heißt jetzt was wegen meinen serialisierten Objekten?
Soll ich die Beans einfach nicht serialisiert machen?


----------



## stg (6. Sep 2013)

Wie sieht die "domain" denn aus und wieso ist sie nicht serialisierbar?
Welchen Zweck erfüllt sie in deiner Applikation?
Sollen (oder können) bestimmte Typen nicht serialisiert werden, so kann man sie mit dem modiefier "transient" versehen.
Eventuell ist es in deinem Fall auch möglich mit DI zu arbeiten, etwa über Annotationen oder du lässt dir über eine Factory-Klasse bei jedem Aufruf ein passendes domain-Objekt erzeugen, falls noch keines referenziert wird.


----------



## lieschen89 (6. Sep 2013)

> Wie sieht die "domain" denn aus und wieso ist sie nicht serialisierbar?
> Welchen Zweck erfüllt sie in deiner Applikation?



Die Domain-Objekte sind, ja ähm, sind die Objekte mit denen eben gearbeitet wird. In diesen ist das Hibernate-Mappig (@Entity @Table....) und meine Services erstellen Neue, fragen nach irgendwelchen Kirterien welche ab auf Basis dessen dann Berechnungen erfolgen etc.
Um eben am Beispiel Auto zu bleiben. Wenn ein User in der Oberfläche alle Autos sehen möchte dann wird das durch ne Abfrage realisiert auf die DB welche eine List<Auto> (Auto = Domain-Objekt) zurückgibt und durch die Service und Controller Schicht zur Bean hochreicht, wo dann eben die Eigenschaften aus dem Objekt über die Attribute rausgeholt und angezeigt wird (#{auto.name})

Serialisierbar kann ich die Domain-Objekte schon machen (Wollte nur wissen ob das üblich ist, kam mir iwie komisch vor, bzw. ob das in meinem Fall Sinn macht). Problem sind nur die Beans. Wenn ich die serialisierbar mache, dann muss ich quasi auch die Controller serlialisierbar machen, deswegen dann die Services und deswegen dann die Daos und hier tritt die Schwiergkeit auf, eben:


```
java.io.NotSerializableException: org.springframework.orm.hibernate3.HibernateTemplate
```

Habs schon versucht als Transient zu markieren. Fehler kommt aber trotzdem.
Beispiel:


```
@SuppressWarnings("serial")
public class MeinDao implements Serializable {

	@Transient 
	private HibernateTemplate hibernateTemplate;

	
	...
	 
	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}		
}
```

(Hab @Transient auch nur an der Variablen oder nur am setter ausprobiert oder an beidem ausporbiert)



> Eventuell ist es in deinem Fall auch möglich mit DI zu arbeiten



Eigentlich lasse ich mir alles 'injecten' über Spring (wie oben im Dao auch das hibernateTemplate).


----------



## nillehammer (8. Sep 2013)

1. Denkfehler
Annotation 
	
	
	
	





```
@Transient
```
 ist was anderes als das Java-Schlüsselwort 
	
	
	
	





```
transient
```
!

```
@Transient
```
 sagt JPA-Providern, dass das Feld nicht persistent sein soll. Das Java Schlüsselwort 
	
	
	
	





```
transient
```
 sagt Java, dass ein Feld nicht serialisiert werden soll. Das sind zwei verschiedene Paar Schuhe. Du müsstest hier zweiteres verwenden.
2. Designfehler
Services haben nichts in Deinen Domain-Objects verloren. Die sollten nur mehr oder minder dumme Datenhaltungsobjekte sein.


----------



## lieschen89 (10. Sep 2013)

> Annotation @Transient ist was anderes als das Java-Schlüsselwort transient



Ah, hab schon gedacht, iwie ist das komisch, da ich nur die Annotation bisher kannte und auch nur im Zusammenhang dass das Feld dann eben nicht persistiert werden soll.
Also quasi


```
private transient  HibernateTemplate hibernateTemplate;
```

Jetzt kommt der Fehler auch nicht mehr. Super, danke.



> Services haben nichts in Deinen Domain-Objects verloren. Die sollten nur mehr oder minder dumme Datenhaltungsobjekte sein.



Hab ich mich irgendwie falsch ausgedrückt oder hab ich dich falsch verstanden? Ich hab IN meinen Domain-Objekte keine Services. Aber die Services benutzen die Domain-Objekte. 
Also eig. nicht nur die Services, eig. in der ganzen Anwendung werden die halt hin und her gereicht.
(Am Beipiel 'Erstellen': Bean nimmt Eingabewerte entgegen, gibt die an Controller weiter. Der erstellt ein neues Auto-Domain-Objekt und füllt es mit den Werten, recht dieses Domain-Objekt dem Service weiter. Der Service reicht es dem Dao weiter und das speichert dann das Auto.)


----------



## nillehammer (10. Sep 2013)

> Hab ich mich irgendwie falsch ausgedrückt oder hab ich dich falsch verstanden? Ich hab IN meinen Domain-Objekte keine Services. Aber die Services benutzen die Domain-Objekte.


Das wäre korrekt so.

Aber die von Dir gezeigten Exceptions und Beispielcode legen den Verdacht nahe, dass es anders ist. Warum hättest Du sonst Daos Serializable machen müsssen?


----------



## lieschen89 (10. Sep 2013)

> Warum hättest Du sonst Daos Serializable machen müsssen?



Weil die Services die Daos halten.



> Serialisierbar kann ich die Domain-Objekte schon machen (Wollte nur wissen ob das üblich ist, kam mir iwie komisch vor, bzw. ob das in meinem Fall Sinn macht).
> Problem sind nur die Beans. Wenn ich die serialisierbar mache, dann muss ich quasi auch die Controller serlialisierbar machen, deswegen dann die Services und deswegen dann die Daos und hier tritt die Schwiergkeit auf


----------

