YAML

Tuesday, December 15th, 2009 | Uncategorized

Ahogy azt egy kedves szomszéd szokta monda, a törpök élete se mindig csak játék és mese. Ez különösen így van, ha a törpök db4o-t használnak. Ráadásul BigDecimal-t akarnak perzisztálni, amihez tartozó kiterjesztés csak a legújabb SNAPSHOT artifactokban van benne.

És valószínű ennek a folyománya az, ami rendszeresen szembe jön, egy exception (hová is lenne az életünk exceptionök nélkül), ami valahogy így néz ki:

Caused by: com.db4o.ext.InvalidSlotException: id: 5182
        at com.db4o.internal.marshall.UnmarshallingContext.invalidSlot(UnmarshallingContext.java:81)
        at com.db4o.internal.marshall.UnmarshallingContext.read(UnmarshallingContext.java:49)
        at com.db4o.internal.ObjectReference.read(ObjectReference.java:281)
        at com.db4o.internal.ObjectReference.read(ObjectReference.java:267)
        at com.db4o.internal.ObjectContainerBase.getHardObjectReferenceById(ObjectContainerBase.java:956)
        at com.db4o.internal.marshall.AbstractReadContext.classMetadataForObjectId(AbstractReadContext.java:85)
        at com.db4o.internal.marshall.AbstractReadContext.readObject(AbstractReadContext.java:57)
        at com.db4o.internal.marshall.AbstractReadContext.readAtCurrentSeekPosition(AbstractReadContext.java:46)
        at com.db4o.internal.OpenTypeHandler.read(OpenTypeHandler.java:172)
        at com.db4o.internal.Handlers4.readValueType(Handlers4.java:313)
        at com.db4o.internal.marshall.AbstractReadContext.readAtCurrentSeekPosition(AbstractReadContext.java:48)

És így tovább.

A hiba teljesen kiszámíthatatlanul, ugyanakkor jól reprodukálhatóan előjön. Pl. előveszek egy backup db4o file-t, megnyitom, teszek-veszek benne, lezárom az alkalmazást. A következő megnyitáskor már nem nyílik meg az adatbázis. Ha viszont ugyanazt a cselekmény sort újra végigviszem az elmentett db4o file-on ugyanúgy elszáll.

Tehát előszőr is ki kéne dobni a db4o-ból a BigDecimal-okat, amihez át kéne konvertálni a sémát. (Tegyük fel, hogy egy számlázó programban sosem fogok beleütközni a float korlátaiba). Ha nincs több BigDecimal mezőm, akkor használhatom a stabil db4o változatot. A másik meg, hogy szükségem lesz egy dump file formátumra. Egyrészt mivel féltem a már bent lévő adatokat, másrészt mert a mező típus konvertálás is nagy szívás egy meglévő db4o adatbázison, az egyik legegyszerűbb megoldás, hogy kidumpolom az adatbázist, majd típus refaktor után vissza.

Mi legyen a dump formátum. Kapásból a JAXB és Json jutnak eszembe, de ezek ahogy én tudom nem támogatják a referenciák kezelését. (Ha az objektum fában többszőr is előfordul ugyanaz az objektum, akkor visszatöltés után ne két, hanem csak egy objektum legyen, amire két helyről mutat referencia.

És itt jön kébe a YAML, amit pont tudja mindezt.

Előszőr a jYaml-t próbáltam, ami alapból egyszerűen működik, de régóta nem fejlesztik, és túlságosan is elnézően bánt a Yaml fájl hibáival. Aztán jött a Snakeyaml. Ez már tette a dolgát mint a kisangyal.

Objektum mentése:

Yaml yaml = new Yaml();
yaml.dump(eztmentemel, new FileWriter(file));

Objektum betöltése:

Yaml yaml = new Yaml();
DatabaseBackup backup = (DatabaseBackup) yaml.load(new FileInputStream(file));

Maga a Yaml file meg valahogy így néz ki.

!!net.anzix.nona.entity.DatabaseBackup
felhasznalok:
- email: geza@hutira.net
  partner: &id001
    partnerek:
    - &id005
      partnerek: []
      szamlak: []
      torzs: {adoszam: null, bankszamlaSzam: null, nev: Asztal kft., szamlaCim: Sötét út 20.,
        szamlaIrsz: '1111', szamlaVaros: Budapest}
      tulajdonos: *id001
....

Itt már rögtön látszik is a referencia kezelése. A partner objektum instance azonosítója id001, és a partnerek listában található egyik partner tulajdonos mezője pont erre mutat vissza referenciával.

Mivel a db4o-val egy paranccsal elmenti az objektumfát, ezért 3 sorban tudok backupolni és visszatölteni a backupot, és a yaml file-t minimálisan módosítgatva (segít a nagyerejű grep parancs) még a típus konverziókat is sikerült viszonylag kis fájdalom árán meglépni.

Yaml a mi barátunk.

Tags: ,

3 Comments to YAML

Andrey
2009/12/16

Just for your information.
The ‘!!net.anzix.nona.entity.DatabaseBackup’ global tag is redundant for SnakeYAML. It can parse the YAML document without it. Please take a look at JavaBeanLoader.

Thank you for using SnakeYAML and good luck,
Andrey

boci
2009/12/16

YAML for president…
Azert db4o utan csinalhatnal egy kis kiterot neodatis fele hatha nemszar (tesztek szerint joval gyorsabb mint db4o, beepitett criteria api stb)

Kivancsi lennek atapasztalatokra ;)

Leave a comment

Meta

Search