Objekte abspeichern

mas666

Mitglied
Hallo zusammen,

Ich suche eine Möglichkeit, ein Objekt in Java intelligent abzuspeichern. Im Moment mach ich das mit Serialize und das funktioniert eigentlich ganz gut. Wenn ich aber die Klasse eines gespeicherten Objektes verändere, lässt sich das serialisierte Objekt nicht mehr laden (ist ja auch logisch).

Ich möchte nun aber sicherstellen, dass das Objekt trotzdem geladen werden kann. Ich habe versucht, eine Konvertierungsfunktion zu schreiben aber mein Objekt enthält nebst normalen Java-Datentypen auch eigene Objekte, welche sich unter Umständen auch ändern können. Das hiesse, dass ich bei einer Änderung einer beliebigen Klasse die mitserialisiert wird (ca 30 Stk.) dem Hauptobjekt eine neue Versionsnummer verpassen müsste, dass ich eine weitere konvertierungsmethode schreiben müsste und, dass ich die vorherigen Klassen im Projekt mitführe, da ich sie benötige um die Konvertierung vorzunehmen.

Fazit: Bei jedem neuen Release würde sich die Software um eine Menge Klassen erweitern, die nur dazu da sind, alte Objekte zu konvertieren. Die Konvertierung wäre schlecht zu überblicken, usw.

Ich denke, theoretisch könnte ich alle Werte plaintext aufbereiten, laden und auf das aktuelle Objekt übertragen. Nicht vorhandene Werte werden mit Standardwerten gefüllt. Mein Objekt besteht allerdings aus sehr vielen Tabellen mit sehr vielen Werten. Es dürften bei normaler Grösse eines Projekts in meiner Software mehrere tausend Einträge sein.

Gibt es andere, bessere Strategien? Existieren in Java Standard-Mechanismen zum Lösen dieses Problems?

Ich bin für jeden Tipp dankbar.

Gruss
mas
 
Hallo,

Software wächst relativ schnell und es ist einfach Änderungen einzubauen die nicht mehr binärkompatibel sind. Wie man dem entgegentreten kann findest du hier:

http://wiki.eclipse.org/index.php/Evolving_Java-based_APIs
http://wiki.eclipse.org/Evolving_Java-based_APIs_2
http://wiki.eclipse.org/Evolving_Java-based_APIs_3
http://www.eclipsecon.org/2008/index.php?page=sub/&id=65

Ansonsten lohnt es sich die Daten in einem XML Format zu serialisieren. Dann ist sichergestellt, dass man die alten Daten auf jedenfall noch einlesen kann. Das XML / Object Mapping kann man dann über entsprechende Frameworks über Java Annotations, Code oder eine weitere XML Mapping Datei erledigen.

Was auch noch gut funktioniert ist keine konkrete Implementierung mehr für jedes Datenmodell zu haben und statt dessen mit einer generischen Repräsentation und Interfaces zu arbeiten:
http://www.tutorials.de/forum/java/250691-dynamisch-zur-laufzeit-getypte-modelle-erzeugen.html

Dabei kann man dann wie im Eclipse Way gezeigt auch gut mit Veränderungen auskommen.

interface Model{
String data;
String value;
}

interface Model1 extends Model{ // kommt später hinzu...
String anotherValue;
}

interface Model2 extends Model1{
String anotherValueAgain;
}

Die Benamung ist hier natürlich etwas fragwürdig...

Das sieht natürlich so aus, als würde das Domain Model dann zu reinen ValueObjects / DTOs werden, aber dass muss nicht sein.
Auch bei solch einem generischen Model kann man Methoden definieren. Der generische DataModelWrapper braucht dann aber ein Mapping von einer Methode des interfaces zu einer konkreten Implementierung (Strategy).

Groß Tom
 
Herzlichen Dank für Deine Rückmeldung und für Deine wertvollen Tipps.

Ich habe schon herumprobiert, wie ich einfach ein XML erstellen kann. Leider habe ich den Bogen noch nicht ganz raus. Es muss doch etwas geben, dass diese Seralisation für mich übernimmt, oder?

Ich habe folgendes Beispiel ausprobiert:

Code:
public class Foo {
   private String foo ;
  
   public void setFoo(String s) {
     foo = s;
   }
   
   public String getFoo() {
     return foo;
   }
}

Code:
import java.beans.XMLEncoder;
import java.beans.XMLDecoder;
import java.io.*;

public class FooHelper {
    public static void write(Foo f, String filename) throws Exception{
        XMLEncoder encoder =
           new XMLEncoder(
              new BufferedOutputStream(
                new FileOutputStream(filename)));
        encoder.writeObject(f);
        encoder.close();
    }

    public static Foo read(String filename) throws Exception {
        XMLDecoder decoder =
            new XMLDecoder(new BufferedInputStream(
                new FileInputStream(filename)));
        Foo o = (Foo)decoder.readObject();
        decoder.close();
        return o;
    }
}

Code:
public class FooTest {
    public static void main (String [] args) throws Exception{
        Foo  f1 = new Foo();
        f1.setFoo("bar");
        FooHelper.write(f1, "foo.xml");

        Foo f2 = FooHelper.read("foo.xml");
        System.out.println("Foo" + f2.getFoo());
        // the output : Foobar
    }
}

Folgendes Ergebnis wird erwartet (nach dem Beispiel auf http://www.rgagnon.com/javadetails/java-0470.html):

Code:
<?xml version="1.0" encoding="UTF-8"?> 
<java version="1.5.0-beta" class="java.beans.XMLDecoder"> 
 <object class="Foo"> 
  <void property="foo"> 
   <string>bar</string> 
  </void> 
 </object> 
</JAVA>

Das funktioniert. Sobald ich aber weitere Felder in Foo definiere (Eigene Klassen) funktioniert das ganze nicht mehr.

Code:
java.lang.InstantiationException: path.to.my.Class

Ist diese Methode zu empfehlen? Ich habe mir auch http://www.tutorials.de/forum/java/250691-dynamisch-zur-laufzeit-getypte-modelle-erzeugen.html angesehen, mir fehlt allerdings noch ein Wenig der Ansatz zur Realisierung. Ich werde da noch ein wenig genauer drüber gehen müssen.

Gruss
mas
 
Hallo,

Ich habe schon herumprobiert, wie ich einfach ein XML erstellen kann. Leider habe ich den Bogen noch nicht ganz raus. Es muss doch etwas geben, dass diese Seralisation für mich übernimmt, oder?
Klar:
Xstream
XMLBeans
JAXB
Castor
etc.

Gruß Tom
 
Zurück