1 / 75

Disseny de la persistència JDO i frameworks de persistència

Disseny de la persistència JDO i frameworks de persistència. Toni Navarrete Enginyeria del Software II – UPF 200 4. Recordatori: problemes (i aventatges) d’altres solucions. Serialitzatió Avantantges: Estàndard en qualsevol ambient Java Fàcil d’utilitzar

Download Presentation

Disseny de la persistència JDO i frameworks de persistència

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Disseny de la persistència JDO i frameworks de persistència Toni Navarrete Enginyeria del Software II – UPF 2004

  2. Recordatori: problemes (i aventatges) d’altres solucions • Serialitzatió • Avantantges: • Estàndard en qualsevol ambient Java • Fàcil d’utilitzar • El model de dades és directament el de les classes (aprofita OO) • Inconvenients: • No té les característiques d’un gestor de BD robust • Per exemple, índexs, transaccions,... • No és escalable

  3. Recordatori: problemes (i aventatges) d’altres solucions • JDBC • Dóna accés a SQL • Usa el model relacional de SQL • No el model orientat a objectes de Java • Procedimental en lloc d’OO • El processament de dades es fa mitjançant SQL i no Java • Les operacions són expressades en relació a taules, files i columnes • SQL no està realment estandaritzat, amb la qual cosa la portabilitat no sempre és real

  4. Recordatori: problemes (i aventatges) d’altres solucions • Quan s’utilitza JDBC, el programador està obligat a treballar amb dos models de dades diferents, així com amb dos paradigmes i llenguatges d’accés a les dades distints. • El resultat sol ser que s’escriu codi Java procedural per manipular les taules. No OO

  5. Conseqüència • Moltes organitzacions comencen a desenvolupar el seu propi framework per a persistència i O/R mapping, que permeti els seus objectes interactuar amb la BD de forma transparent • Exemples • Castor • Apache ObJectRelationalBridge (OJB) • ODMG 3.0, desenvolupat pelObject Data Management Group (ODMG). Inicalment en C++ i Smaltalk, ha estat una de les bases de JDO i n’és un subconjunt

  6. Problemes (i avantatges) d’altres solucions • ORM propietaris (Object-Relational Mapping) • Riscos significatius a l’hora de desenvolupar un ORM propi • Limitacions d’APIs ORM propietàries. Adoptar un API propietària és sempre arriscat. A moltes implementacions: • Falta d’encapsulació causada per la necessitat de definir mètodes getter i setter públics per als atributs persistents • Extensibilitat limitada per la falta de soport de l’herència • Falta de soport de referències polimòrfiques • Dependència absoluta d’un venedor

  7. JDO • És una nova iniciativa de la comunitat Java per crear un framework estandaritzat per a persistència (de la mateixa que Swing ho és per a interfície gràfica) • JDO és només una especificació, de la qual els fabricants de software faran implementacions (a vegades lliures, a vegades no) • Normalment parlarem de JDO per accedir a BDR, però pot ser qualsevol forma d’emmagatzemantge permanent (XML, fitxers,...) • Sun produeix el JDORI (JDO Reference Implementation) com a una implementació per demostrar que l’especificació és vàlida. Però no està pensada per explotació en entorns reals

  8. JDO • JDO: capacitats de BD de JDBC amb la integració Java de la serialització • JDO usa el model d’objectes Java • Les instàncies tenen un identificador únic (OID únic) • Soporta transaccions • Emmagatzemar instàncies, recuperar-les i modificar-es és transparent • Resum: mínima intrusió i màxima transparència

  9. Comparació JDO amb les altres alternatives • EJB també defineix un mecanisme de persistència transparent (Container Managed Persistence, CMP), però EJB és una arquitectura complexa i amb més overhead que JDO • Serialització també és OO però no és apte per treballar amb grans volums de dades, no és escalable, i no té suport per índexs, transaccions i demés mecanismes d’un SGBD

  10. JDO i JDBC • JDO no substituirà JDBC • Són complementàries • Les implementacions de JDO solen utilitzar JDBC per sota per connectar-se a la BD • JDBC és útil per gestionar connexions amb la BD • JDBC és força sòlid • JDBC està soportat per la majoria de fabricants de SGBC

  11. JDO JDOcentral.com: A comparion between Java Data Objects (JDO), Serialization and JDBC for Java Persistance

  12. Exemple d’una petita aplicació JDO amb la JDORI

  13. Exemple d’una classe persistent amb JDO package es2; public class Persona { String nom, cognom; int anyNaixement = 0; public Persona() {} // a JDO és obligatori que hi hagi un constructor sense arguments public Persona(String nom, String cognom, int anyNaixement) { this.nom = nom; this.cognom = cognom; this. anyNaixement = anyNaixement; } public void setNom(String nom) { this.nom = nom; } public String getNom() { return this.nom; } public void setCognom(String cognom) { this.cognom = cognom; } public String getCognom() { return this.cognom; } public void setAnyNaixement(int anyNaixement) { this. anyNaixement = anyNaixement; } public int getAnyNaixement() { return this.anyNaixement; } }

  14. Declaració de classes persistents • L’únic requeriment és que la classe ha de tenir un constructor sense arguments • Ara podem crear instàncies d’aquesta classe Person i guardar-las a la BDR • JDO utilitza un fitxer de metadades per dir quines classes seran persistents i reflectir tota la informació relacionada amb la persistència (ho veurem amb més detall més endavant) • Fitxer amb extensió .jdo

  15. Exemple de fitxer de metadades (es2.jdo) <?xml version= "1.0" encoding="UTF-8"?> <!DOCTYPE jdo SYSTEM "file:/C:/.../jdori-1_0/srcjavax/jdo/jdo.dtd"> <jdo> <package name= "es2" > <class name="Persona" /> </package> </jdo> o <!DOCTYPE jdo PUBLIC “-//Sun Microsystems, Inc.//DTD Java Data Objects Metadata 1.0//EN" "http://java.sun.com/dtd/jdo_1_0.dtd"> • Restricció: • El nom del fitxer és el del paquet (al directori arrel) o també es pot fer separat per classes (Persona.jdo en el nostre cas) i van dins del directori es2

  16. Jars necessaris • JDO es pot baixar de www.jcp.org (JSR-12) • Per treballar amb la implementació de referència: • jdo.jar • Les interfícies estàndard i les classes definides a l’especificació JDO • jdori.jar • La implementació de referència de Sun • btree.jar • Implementa un petit gestor d’emmagatzament per la JDORI de Sun • jta.tar • Java Transaction API que usa JDO per definir transaccions • antlr.jar • Serveix per parsejar el llenguatges de consultes de JDO • xerces.jar • Per parsejar XML

  17. Enhancement • Un cop que hem compilat la(s) classe(s), hem de fer un enhancement • Això sobre-escriu els fitxers de bytecode (.class) afegint dades i mètodes que permeten les instàncies de la classe ser manegades per la implementació JDO • Ho fa a partir del fitxer de metadades • Cada fabricant de JDO pot incloure el seu enhancer, però suposadament són compatibles • JDORI porta el reference enhancer

  18. Enhancement

  19. Enhancement

  20. Enhancement • java com.sun.jdori.enhancer.Main es2.jdo es2/Persona.class • Algunes opcions: • -v (verbose) • -d (a un directori distint, sense sobreescriure el .class original): • java com.sun.jdori.enhancer.Main -v -d enhanced es2.jdo es2/Persona.class • Cada fabricant d’implementacions JDO té el seu enhancer que es crida de forma diferent • Noteu que l’enhancement és independent del magatzem de dades que utilitzem després

  21. Fent una aplicació • Ara farem una aplicació que crea instàncies de Persona i les guarda a una BD • JDORI porta un petit gestor com a referència que es diu FOStore (File Object Store)

  22. Estructura de classes de JDO • El nucli de JDO és la interfície PersistenceManager, que és la que manega la connexió amb un magatzem de dades

  23. Estructura de classes de JDO • Per obtenir i configurar un PersistenceManager es fa mitjançant la interfície PersistenceManagerFactory • A la vegada, el PersistenceManagerFactory s’obté a partir d’un mètode estàtic de la classe JDOHelper, segons unes propietats (url de connexió, login, password i el nom de la implementació de JDO que utilitzem)

  24. Estructura de classes de JDO • Exemple de propietats per crear un PersistenceManagerFactory: javax.jdo.PersistenceManagerFactoryClass=com.sun.jdori.fostore.FOStorePMF javax.jdo.option.ConnectionURL =fostore:database/fostoredb javax.jdo.option.ConnectionUserName=toni javax.jdo.option.ConnectionPassword=toni • Aquestes propietats poden estar a un fitxer (típciament jdo.properties) o ser configurades des de programa

  25. Estructura de classes de JDO • Un PersistenceManager té associat una instància de la interfície JDO Transaction, per a controlar el començament i finalització d’una transacció • Per obtenir la instància de Transaction ho fem amb el mètode currentTransaction de la instància de PersistenceManager • En JDO tota acció que hagi de modificar la BD estarà emmarcada dins d’una transacció • Usarem els mètodes begin, commit i rollback de la instància de Transaction

  26. FOStore • JDORI porta un petit gestor com a referència que es diu FOStore (File Object Store) • Anem a crear una BD per guardar les futures instàncies de la classe Persones • jdo.properties • Directori database • CreateDatabase.java

  27. package es2; import java.io.FileInputStream; import java.io.InputStream; import java.util.Properties; import javax.jdo.JDOHelper; import javax.jdo.PersistenceManagerFactory; import javax.jdo.PersistenceManager; import javax.jdo.Transaction; public class CreateDatabase{ public static void main(String[] args){ create(); } public static void create(){ try{ InputStream propertyStream = new FileInputStream("es2/jdo.properties"); Properties jdoproperties = new Properties(); jdoproperties.load(propertyStream); jdoproperties.put("com.sun.jdori.option.ConnectionCreate","true"); PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(jdoproperties); PersistenceManager pm = pmf.getPersistenceManager(); Transaction tx = pm.currentTransaction(); tx.begin(); tx.commit(); } catch (Exception e) { System.err.println("Exception creating db"); e.printStackTrace(); System.exit(-1); } } } Creació d’una BD en FOStore • Aquest codi crea un magatzem al directori database • Propietat com.sun.jdori.option.ConnectionCreate a true

  28. Creant l’aplicació package es2; import java.io.FileInputStream; import java.io.InputStream; import java.util.Properties; import java.util.Map; import java.util.HashMap; import javax.jdo.JDOHelper; import javax.jdo.PersistenceManagerFactory; import javax.jdo.PersistenceManager; import javax.jdo.Transaction; public class Aplicacio1{ protected PersistenceManagerFactory pmf; protected PersistenceManager pm; protected Transaction tx; public Aplicacio1() { try{ InputStream propertyStream = new FileInputStream("es2/jdo.properties"); Properties jdoproperties = new Properties(); jdoproperties.load(propertyStream); pmf = JDOHelper.getPersistenceManagerFactory(jdoproperties); pm = pmf.getPersistenceManager(); tx = pm.currentTransaction(); } catch (Exception e) { System.err.println("Exception creating db"); e.printStackTrace(); System.exit(-1); } } public void executeTransaction() { try{ tx.begin(); Persona p = new Persona("toni","navarrete",1973); pm.makePersistent(p); tx.commit(); } catch (Throwable exception){ exception.printStackTrace(System.err); if (tx.isActive()) tx.rollback(); } } public static void main(String[] args) { Aplicacio1 ap = new Aplicacio1(); ap.executeTransaction(); } }

  29. Sobre les propietats • També es poden especificar les propietats dins del codi: ... Properties props = new Properties(); props.setProperty("javax.jdo.PersistenceManagerFactoryClass", "com.sun.jdori.fostore.FOStorePMF "); props.setProperty("javax.jdo.option.ConnectionURL", "fostore:database/fostoredb"); props.setProperty("javax.jdo.option.ConnectionUserName",“toni"); props.setProperty("javax.jdo.option.ConnectionPassword",“toni"); props.setProperty("javax.jdo.option.Optimistic",“false"); pmf = JDOHelper.getPersistenceManagerFactory(jdoproperties);

  30. Creant l’aplicació amb una millor organització package es2; import java.io.FileInputStream; import java.io.InputStream; import java.util.Properties; import javax.jdo.JDOHelper; import javax.jdo.PersistenceManagerFactory; import javax.jdo.PersistenceManager; import javax.jdo.Transaction; public abstract class Aplicacio{ protected PersistenceManagerFactory pmf; protected PersistenceManager pm; protected Transaction tx; public abstract void execute(); public Aplicacio() { try{ InputStream propertyStream = new FileInputStream("es2/jdo.properties"); Properties jdoproperties = new Properties(); jdoproperties.load(propertyStream); pmf = JDOHelper.getPersistenceManagerFactory(jdoproperties); pm = pmf.getPersistenceManager(); tx = pm.currentTransaction(); } catch (Exception e) { System.err.println("Exception creating db"); e.printStackTrace(); System.exit(-1); } } public void executeTransaction() { try{ tx.begin(); execute(); tx.commit(); } catch (Throwable exception){ exception.printStackTrace(System.err); if (tx.isActive()) tx.rollback(); } } } package es2; public class CrearPersones extends Aplicacio{ public static void main(String[] args) { CrearPersones cp = new CrearPersones(); cp.executeTransaction(); } public void execute() { Persona p1 = new Persona("pasqual","maragall",1950); pm.makePersistent(p1); Persona p2 = new Persona("artur","mas",1955); pm.makePersistent(p2); } }

  31. Consultes • Extent és una interfície que permet accedir a totes les instàncies d’una classe persistent • Mètode getExtent del PersistenceManager Extent extent = pm.getExtent(Persona.class,false); /* el segon paràmetre indica si també considerar les instàncies de les subclasses */

  32. Consulta de totes les persones emmagatzemades package es2; import java.util.Iterator; import javax.jdo.Extent; public class LlistatPersones extends Aplicacio{ public static void main(String[] args) { LlistatPersones lp = new LlistatPersones(); lp.executeTransaction(); } public void execute() { Extent extent = pm.getExtent(Persona.class,false); Iterator it = extent.iterator(); while (it.hasNext()) { Persona p = (Persona)it.next(); System.out.println("Nom: " + p.getNom()); System.out.println("Cognom: " + p.getCognom()); System.out.println("Any naixement: " + p.getAnyNaixement()); System.out.println(); } extent.close(it); } }

  33. Consulta de totes les persones emmagatzemades (sense transacció) package es2; import java.util.Iterator; import javax.jdo.Extent; public class LlistatPersones extends Aplicacio{ public static void main(String[] args) { LlistatPersones lp = new LlistatPersones(); lp.consulta(); } public void consulta() { Extent extent = pm.getExtent(Persona.class,false); Iterator it = extent.iterator(); while (it.hasNext()) { Persona p = (Persona)it.next(); System.out.println("Nom: " + p.getNom()); System.out.println("Cognom: " + p.getCognom()); System.out.println("Any naixement: " + p.getAnyNaixement()); System.out.println(); } extent.close(it); } public void execute() {} }

  34. Consultes i filtres • La interfície Query permet definir filtres sobre un Extent, per fer consultes més específiques (i no de tots els elements) • Quan es crea una Query s’especifica l’Extent i la condició: Query q = pm.newQuery(extent,"nom == nomPersona"); q.declareParameters("String nomPersona"); • També es pot crear la Query directament sobre la classe: Query q = pm.newQuery(Persona.class,"nom==\"toni\""); • En especificar la condició podem utilitzar els operadors comparatius, aritmètics,... de Java

  35. Consulta del cognom d’una persona concreta package es2; import java.util.Iterator; import java.util.Collection; import javax.jdo.Extent; import javax.jdo.Query; public class CognomPersona extends Aplicacio{ public static void main(String[] args) { CognomPersona cp = new CognomPersona(); cp.executeTransaction(); } public void execute() { Extent extent = pm.getExtent(Persona.class,false); String nomPersona = new String("toni"); Query q = pm.newQuery(extent,"nom == nomPersona"); q.declareParameters("String nomPersona"); Collection result = (Collection)q.execute(nomPersona); Iterator it = result.iterator(); if (it.hasNext()) { Persona p = (Persona)it.next(); System.out.println("Nom: " + p.getNom()); System.out.println("Cognom: " + p.getCognom()); System.out.println("Any naixement: " + p.getAnyNaixement()); } q.close(result); } }

  36. Més coses • Treballar amb un gestor de veritat • Una altra implementació de JDO: JPOX • És opensource i té suport per treballar amb nombrosos SGBDs (MySQL, PostgreSQL i Oracle entre d’altres) • Associacions entre classes (relacions entre taules) i herència • Generació automàtica de l’esquema de la BD • Capacitat per configurar el mapping objecte/relacional a l’hora de crear les taules • Permet: • Insercions, eliminacions i modificacions d’objectes • Consultes • Persistència transitiva

  37. Un exemple més complet (amb JPOX) Grup Persona 0..* 0..1 Empleat

  38. Persona package es2; public class Persona { String nom, cognom; int anyNaixement = 0; Grup grupp; public Persona() {} // a JDO és obligatori que hi hagi un constructor sense arguments public Persona(String nom, String cognom, int anyNaixement) { this.nom = nom; this.cognom = cognom; this. anyNaixement = anyNaixement; } public void setNom(String nom) { this.nom = nom; } public String getNom() { return this.nom; } public void setCognom(String cognom) { this.cognom = cognom; } public String getCognom() { return this.cognom; } public void setAnyNaixement(int anyNaixement) { this. anyNaixement = anyNaixement; } public int getAnyNaixement() { return this.anyNaixement; } public void setGrup(Grup g) { this.grupp = g; } public Grup getGrup() { return this.grupp; } }

  39. Grup package es2; import java.util.*; public class Grup{ String nom; Set persones; public Grup() {} // a JDO és obligatori que hi hagi un constructor sense arguments public Grup(String nom){ this.nom=nom; this.persones=new HashSet(); } public void setNom(String nom){ this.nom = nom; } public String getNom() { return this.nom; } public void afegeixPersona(Persona p) { this.persones.add(p); p.setGrup(this); } public Set getPersones() { return this.persones; } } Suporta diversos tipus per a les col·leccions: • Collection • Set • HashSet • Map • List • ArrayList • HashMap • Hashtable • LinkedList • TreeMap • TreeSet • Vector

  40. Empleat package es2; public class Empleat extends Persona{ int salari; public Empleat() {} // a JDO és obligatori que hi hagi un constructor sense arguments public Empleat(String nom, String cognom, int anyNaixement, int salari) { this.nom = nom; this.cognom = cognom; this.anyNaixement = anyNaixement; this.salari=salari; } public void setSalari(int salari) { this.salari = salari; } public int getSalari() { return this.salari; } }

  41. Fitxer de metadades (package.jdo) <?xml version="1.0"?> <!DOCTYPE jdo PUBLIC "-//Sun Microsystems, Inc.//DTD Java Data Objects Metadata 1.0//EN" "http://java.sun.com/dtd/jdo_1_0.dtd"> <jdo> <package name="es2"> <class name="Persona"> <field name="grupp" persistence-modifier="persistent" /> </class> <class name="Empleat" persistence-capable-superclass="es2.Persona"/> <class name="Grup"> <field name="persones" mapped-by="grupp"> <collection element-type="es2.Persona"/> </field> </class> </package> </jdo> • Comanda d’Enhancement: java -cp "build;lib/jpox.jar;lib/jpox-enhancer.jar;lib/bcel.jar;lib/jdo.jar; lib/log4j.jar" org.jpox.enhancer.JPOXEnhancer build/es2/package.jdo

  42. Extensions als elements de metadades • Els fabricants d’implementacions JDO poden crear les seves extensions als elements del fitxers de metadades • Lògicament no seran portables a altres implementacions • Es poden definir paràmetres referents a com emmagatzemar les dades, com per exemple crear índexs, definir primary-keys, especificar longituds de strings,... • Exemple: <field name="name"> <extension vendor-name="jpox“key="length" value="max 100"/> </field>

  43. Tractament de les relacions. Relacions 1 a 1 • Single-ended <package name="mydomain"> <class name="User" identity-type="datastore"> <field name="login" persistence-modifier="persistent"> <extension vendor-name="jpox" key="length" value="max 20"/> </field> </class> <class name="Account" identity-type="datastore"> <field name="firstName" persistence-modifier="persistent"> <extension vendor-name="jpox" key="length" value="max 50"/> </field> <field name="secondName" persistence-modifier="persistent"> <extension vendor-name="jpox" key="length" value="max 50"/> </field> <field name="user" persistence-modifier="persistent"> </field> </class> </package>

  44. Tractament de les relacions. Relacions 1 a 1 • Double-ended <package name="mydomain"> <class name="User" identity-type="datastore"> <field name="login" persistence-modifier="persistent"> <extension vendor-name="jpox" key="length" value="max 20"/> </field> <field name="account" persistence-modifier="persistent"> </field> </class> <class name="Account" identity-type="datastore"> <field name="firstName" persistence-modifier="persistent"> <extension vendor-name="jpox" key="length" value="max 50"/> </field> <field name="secondName" persistence-modifier="persistent"> <extension vendor-name="jpox" key="length" value="max 50"/> </field> <field name="user" persistence-modifier="persistent"> </field> </class> </package>

  45. Tractament de les relacions. Relacions 1 a N • Normal (amb Set): <package name="mydomain"> <class name="Address" identity-type="datastore"> <field name="city" persistence-modifier="persistent"> <extension vendor-name="jpox" key="length" value="max 50"/> </field> <field name="street" persistence-modifier="persistent"> <extension vendor-name="jpox" key="length" value="max 50"/> </field> </class> <class name="Account" identity-type="datastore"> <field name="firstname" persistence-modifier="persistent"> <extension vendor-name="jpox" key="length" value="max 100"/> </field> <field name="lastname" persistence-modifier="persistent"> <extension vendor-name="jpox" key="length" value="max 100"/> </field> <field name="addresses" persistence-modifier="persistent"> <collection element-type="mydomain.Address"/> </field> </class> </package>

  46. Tractament de les relacions. Relacions 1 a N • Inverse-bidirectional (amb Set): <package name="mydomain"> <class name="Address" identity-type="datastore"> <field name="city" persistence-modifier="persistent"> <extension vendor-name="jpox" key="length" value="max 50"/> </field> <field name="street" persistence-modifier="persistent"> <extension vendor-name="jpox" key="length" value="max 50"/> </field> <field name="account" persistence-modifier="persistent"> <extension vendor-name="jpox" key="collection-field" value="addresses"/> </field> </class> <class name="Account" identity-type="datastore"> <field name="firstname" persistence-modifier="persistent"> <extension vendor-name="jpox" key="length" value="max 100"/> </field> <field name="lastname" persistence-modifier="persistent"> <extension vendor-name="jpox" key="length" value="max 100"/> </field> <field name="addresses" persistence-modifier="persistent"> <collection element-type="mydomain.Address"> <extension vendor-name="jpox" key="owner-field" value="account"/> <collection/> </field> </class> </package>

  47. Tractament de les relacions. Relacions M a N • Amb dues taules de join (amb Set): <package name="mydomain"> <class name="Product" identity-type="datastore"> <field name="name" persistence-modifier="persistent"> <extension vendor-name="jpox" key="length" value="max 50"/> </field> <field name="price" persistence-modifier="persistent"> </field> <field name="suppliers" persistence-modifier="persistent"> <collection element-type="mydomain.Supplier"> <collection/> </field> </class> <class name="Supplier" identity-type="datastore"> <field name="name" persistence-modifier="persistent"> <extension vendor-name="jpox" key="length" value="max 100"/> </field> <field name="products" persistence-modifier="persistent"> <collection element-type="mydomain.Product"> <collection/> </field> </class> </package>

  48. Tractament de les relacions. Relacions M a N • Amb només una taula de join (amb Set): <package name="mydomain"> <class name="Product" identity-type="datastore"> <field name="name" persistence-modifier="persistent"> <extension vendor-name="jpox" key="length" value="max 50"/> </field> <field name="price" persistence-modifier="persistent"> </field> <field name="suppliers" persistence-modifier="persistent"> <collection element-type="mydomain.Supplier"> <extension vendor-name="jpox" key="table-name" value="PRODUCTS_SUPPLIERS"/> <extension vendor-name="jpox" key="owner-column-name" value="PRODUCT_ID"/> <extension vendor-name="jpox" key="element-column-name" value="SUPPLIER_ID"/> <collection/> </field> </class> <class name="Supplier" identity-type="datastore"> <field name="name" persistence-modifier="persistent"> <extension vendor-name="jpox" key="length" value="max 100"/> </field> <field name="products" persistence-modifier="persistent"> <collection element-type="mydomain.Product"> <extension vendor-name="jpox" key="table-name" value="PRODUCTS_SUPPLIERS"/> <extension vendor-name="jpox" key="owner-column-name" value="SUPPLIER_ID"/> <extension vendor-name="jpox" key="element-column-name" value="PRODUCT_ID"/> <collection/> </field> </class> </package>

  49. Tractament de l’herència • Utilitza una taula per a cada classe de l’arbre d’herència, on cada taula contindrà només els atributs propis de la classe (no duplicació d’atributs a diferents classes) • Recordatori: solució 3 del tema “Disseny de la persistència. Introducció i mapping objecte/relacional” • S’espera que en futures versions sigui configurable. Altres implementacions de JDO ho permeten

  50. Tractament de l’herència • Exemple: <package name="org.jpox.sample.store"> <class name="Product"> <field name="name"> <extension vendor-name="jpox" key="length" value="max 100"/> </field> <field name="description"> <extension vendor-name="jpox" key="length" value="max 255"/> </field> <field name="price"/> </class> <class name="Book" persistence-capable-superclass="org.jpox.samples.store.Product"> <field name="isbn"> <extension vendor-name="jpox" key="length" value="max 20"/> </field> <field name="author"> <extension vendor-name="jpox" key="length" value="max 40"/> </field> <field name="title"> <extension vendor-name="jpox" key="length" value="max 40"/> </field> </class> <class name="TravelGuide" persistence-capable-superclass="org.jpox.samples.store.Book"> <field name="country"> <extension vendor-name="jpox" key="length" value="max 40"/> </field> </class> <class name="CompactDisc" persistence-capable-superclass="org.jpox.samples.store.Product"> <field name="artist"> <extension vendor-name="jpox" key="length" value="max 40"/> </field> <field name="title"> <extension vendor-name="jpox" key="length" value="max 40"/> </field> </class> </package>

More Related