Persistence

Document Sample
Persistence Powered By Docstoc
					                           Enterprise
                                Java




          Persistence




v010926      Persistence          1
                                                                      Enterprise
                                                                           Java

                     Persistence Usage
• Scalability
   – disk cheaper than memory
• Fault recovery
   – last known state maintained through recovery
• Parallel processing
   – multiple processors working on shared data source
• Queryable storage
   – locate objects for access
• Checkpointing
   – save current state, potentially as a blob
• Pass by Value
   – pass objects from one process to another so that method
      invocations on the passed object will result in a local method call
      in the process it was passed to
v010926                          Persistence                                 2
                                                  Enterprise
                                                       Java

                       Persistence Types
• Streaming
     – No Persistence
     – Simple Persistence
     – Object Serialization
• Object/RBDMS
     –    Using Blobs
     –    Horizontal Partitioning
     –    Vertical Partitioning
     –    Unification
• OODMBS


v010926                             Persistence          3
                    No Persistence: Client Must                                Enterprise
                                                                                    Java



                          Manage State
• Used when legacy classes not designed with persistence
  built in
     – could be the result of CASE generated code
                              : Client                : Account   DataOutput
                                                                   Stream
          Account
                                         1: get id_ ( )
     id_ : String
     balance_ : double
                                           2: writeBytes()
     ownerId_ : String

                                     3: get balance_ ( )

                                           4: writeInt()


                                     5: get ownerId_ ( )


                                         6: writeBytes




v010926                         Persistence                                           4
      No Persistence: Implementation              Enterprise
                                                       Java



    does not Address Persistence of State
package streaming.nopersist;
public class Account
{
    public String id_;
    public double balance_;
    public String ownerId_;
    public Account(String id,
             double balance, String ownerId) {
        id_ = id;
        balance_ = balance;
        ownerId_ = ownerId;
    }
    public print(java.util.PrintStream) { ... }
}
v010926                 Persistence                      5
                 Client Code                       Enterprise
                                                        Java



          Must Implement Persistence
void save() throws IOException {
   System.out.println("Client saving accounts");
   DataOutputStream ostream = new DataOutputStream(
          new FileOutputStream(stateFile_));
   ostream.writeInt(accounts_.length);
   for(int i=0; i<accounts_.length; i++) {
      ostream.writeInt(accounts_[i].id_.length());
      ostream.writeBytes(accounts_[i].id_);
      ostream.writeDouble(accounts_[i].balance_);
      ostream.writeInt(accounts_[i].ownerId_.length());
      ostream.writeBytes(accounts_[i].ownerId_);
   }
   ostream.close();
 }
v010926                 Persistence                       6
                  Client Code                              Enterprise
                                                                Java



           Must Implement Persistence
void restore() throws IOException {
     DataInputStream istream = new DataInputStream(
               new FileInputStream(stateFile_));
     accounts_ = new Account[istream.readInt()];
     for(int i=0; i<accounts_.length; i++) {
         int len = istream.readInt();
         byte buffer[] = new byte[len];
         istream.readFully(buffer);
         String id = new String(buffer);
         double balance = istream.readDouble();
         len = istream.readInt();
         buffer = new byte[len];
         istream.readFully(buffer);
         String ownerId = new String(buffer);
         accounts_[i] = new Account(id,balance,ownerId);
      }
      istream.close();
 }
v010926                          Persistence                      7
                                                                                                   Enterprise
                                                                                                        Java

                                Simple Persistence
• Class takes over responsibility for state persistence
• Slight improvement over no persistence
                                        : Client              : Account              :DataOutput
                                                                                       Stream

                Account                1: writeExternal (DataOutputStream)
 id_ : String                                                             2: writeBytes()
 balance_ : double
 ownerId_ : String
                                                                      3: writeDouble()
 readExternal (in : DataInputStream)
 writeExternal (out : DataOutput)
                                                                          4: writeBytes()




v010926                                Persistence                                                        8
                Simple Persistence:                               Enterprise
                                                                       Java



               Class Saves Own State
package streaming.simplePersist;
import java.io.PrintStream;
import java.io.IOException;
import java.io.DataInputStream;
import java.io.DataOutputStream;
public class Account
{
    private String id_;
    private double balance_;
    private String ownerId_;
    public Account() { }
    public Account(String id, double balance, String ownerId) {
        id_ = id;
        balance_ = balance;
        ownerId_ = ownerId;
    }
//...

v010926                        Persistence                               9
                 Simple Persistence:                               Enterprise
                                                                        Java



                Class Saves Own State
public void writeExternal(DataOutputStream ostream) throws IOException{
        ostream.writeInt(id_.length());
        ostream.writeBytes(id_);
        ostream.writeDouble(balance_);
        ostream.writeInt(ownerId_.length());
        ostream.writeBytes(ownerId_);
}
public void readExternal(DataInputStream istream) throws IOException {
        int len = istream.readInt();
        byte buffer[] = new byte[len];
        istream.readFully(buffer);
        id_ = new String(buffer);
        balance_ = istream.readDouble();
        len = istream.readInt();
        buffer = new byte[len];
        istream.readFully(buffer);
        ownerId_ = new String(buffer);
}
v010926                          Persistence                          10
                  Simple Persistence:                Enterprise
                                                          Java



                   Client Simplified
• Client shielded from details of save/restore
     void save() throws IOException {
        System.out.println("Client saving accounts");
        DataOutputStream ostream = new DataOutputStream(
               new FileOutputStream(stateFile_));

          ostream.writeInt(accounts_.length);
          for(int i=0; i<accounts_.length; i++) {
             accounts_[i].writeExternal(ostream);
          }

          ostream.close();
     }

v010926                      Persistence                   11
                Simple Persistence:                       Enterprise
                                                               Java



            Client Knows Object’s Class
• Client still must know the class of the object saved/restored
     void restore() throws IOException {
        System.out.println("Client restoring accounts");
        DataInputStream istream = new DataInputStream(
           new FileInputStream(stateFile_));

          accounts_ = new Account[istream.readInt()];
          for(int i=0; i<accounts_.length; i++) {
             accounts_[i] = new Account();
             accounts_[i].readExternal(istream);
          }

          istream.close();
     }
v010926                      Persistence                        12
                                                         Enterprise
                                                              Java

          Simple Persistence Problem
• Objects may have multiple references to them
• An object may be saved multiple times, once for each
  reference
• Multiple clones might be instantiated, one for each
  persisted copy




v010926                   Persistence                          13
                                                                                                                                        Enterprise
                                                                                                                                             Java

                           Simple Persistence Problem
                                                                                                       Account
                                                                                                      id_ : String
1: writeExternal (DataOutputStream)                    2: writeExternal(DataOutputStream)             balance_ : double
                                                                                                                      *
: Client                       1 : Account                                        bob : OwnerState
                                                      4: writeExternal(DataOutputStream)                                            owner_
           3: writeExternal (DataOutputStream)                                                                                   1
                                                                                                                                Owner
                               2 : Account                                       larry : OwnerState
                                                                                                                              name_ : String
                                                                                                                              address_ : String
      5: writeExternal (DataOutputStream)                                                                                     taxId_ : String
                                                                 6: writeExternal(DataOutputStream)
                               3 : Account

                                                                                       7: OwnerState ( )
                            6: readExternal (DataInputStream)                  8: readExternal(DataInputStream)

                            : Client                      1 : Account                                     bob : OwnerState
                                                                                      10: OwnerState ( )
                                       9: readExternal (DataInputStream)      11: readExternal(DataInputStream)

                                                          2 : Account                                    larry : OwnerState

                                                                                      13: OwnerState ( )
                                  12: readExternal (DataInputStream)          14: readExternal(DataInputStream)

                                                          3 : Account                                     bob : OwnerState



 v010926                                                                Persistence                                                           14
        References to Common Objects                                   Enterprise
                                                                            Java



                not Resolved
creating Client with new accounts         Client adopting statefile
elements=3                                Client restoring accounts
   id=1                                   elements=3
   balance=100.0                             id=1
streaming.problem.Owner@173d14-              balance=100.0
    name=bob, taxid=111-11-1111           streaming.problem.Owner@173db9-
   id=2                                       name=bob, taxid=111-11-1111
   balance=200.0                             id=2
streaming.problem.Owner@173d0f-              balance=200.0
    name=larry, taxid=222-22-2222         streaming.problem.Owner@173da8-
   id=3                                       name=larry, taxid=222-22-2222
   balance=300.0                             id=3
streaming.problem.Owner@173d14-              balance=300.0
    name=bob, taxid=111-11-1111           streaming.problem.Owner@173dec-
Client saving accounts
v010926                           Persistence name=bob, taxid=111-11-1111 15
                                                                           Enterprise
                                                                                Java

                           Serialization
• Clients do not need to know the type of the object saved
     – an abstract interface (java.io.Serializable is defined to tag the
       object)
• Clients do not need to know the class of the object restored
     – any abstract super-class or interface of the object is suitable
• Serialization takes care of object references
• Classes take responsibility for their persisted elements
     – delegate to the language (implement java.io,Serializable)
     – tag elements for no persistence (transient)
     – specialize the save process for alternate storage mechanisms
       (supply read/writeObject and/or read/writeExternal methods)

v010926                            Persistence                                   16
                                                           Enterprise
                                                                Java

          Classes add a Tagging Interface
package streaming.serialize;
import java.io.PrintStream;
import java.io.Serializable;
public class Account implements java.io.Serializable
{
    private String id_;
    private double balance_;
    private Owner owner_;

     public Account(String id, double balance, Owner owner) {
         id_ = id;
         balance_ = balance;
         owner_ = owner;
     }
}

v010926                     Persistence                          17
          Associated Classes add the                        Enterprise
                                                                 Java



              Tagging Interface
package streaming.serialize;
import java.io.PrintStream;
import java.io.Serializable;
public class Owner implements Serializable
{
    private String name_;
    private String taxId_;
    public Owner(String name, String taxId) {
        name_ = name;
        taxId_ = taxId;
    }
    public void print(PrintStream out) {
        out.println(this + "- name="+name_ + ", taxid=" +
   taxId_);
    }
}
v010926                    Persistence                            18
              Clients have Simple Save                    Enterprise
                                                               Java



              and Restore Mechanism
void save() throws IOException {
       System.out.println("Client saving accounts");
       ObjectOutputStream ostream = new ObjectOutputStream(
          new FileOutputStream(stateFile_));

          ostream.writeObject(accounts_);
          ostream.close();
}
void restore() throws IOException, ClassNotFoundException {
        System.out.println("Client restoring accounts");
        ObjectInputStream istream = new ObjectInputStream(
              new FileInputStream(stateFile_));
        accounts_ = (Account[])istream.readObject();
        istream.close();
}

v010926                       Persistence                       19
         References to Common Objects                                   Enterprise
                                                                             Java



                 are Resolved
creating Client with new accounts         Client adopting statefile
elements=3                                Client restoring accounts
   id=1                                   elements=3
   balance=100.0                             id=1
streaming.serialize.Owner@173d14-            balance=100.0
    name=bob, taxid=111-11-1111           streaming.serialize.Owner@173f4a-
   id=2                                       name=bob, taxid=111-11-1111
   balance=200.0                             id=2
streaming.serialize.Owner@173d0f-            balance=200.0
    name=larry, taxid=222-22-2222         streaming.serialize.Owner@173f3f-
   id=3                                       name=larry, taxid=222-22-2222
   balance=300.0                             id=3
streaming.serialize.Owner@173d14-            balance=300.0
    name=bob, taxid=111-11-1111           streaming.serialize.Owner@173f4a-
Client saving accounts
v010926                           Persistence name=bob, taxid=111-11-1111     20
            Protecting Attributes from                     Enterprise
                                                                Java



                   Serialization
public class Account implements java.io.Serializable
{
    private String id_;
    private double balance_;
    private Owner owner_;
    private transient Date dummy_; //only intialized on ctor

     public Account(String id, double balance, Owner owner) {
         id_ = id;
         balance_ = balance;
         owner_ = owner;
         dummy_ = new Date();
     }




v010926                     Persistence                          21
                 Protecting Attributes from                                               Enterprise
                                                                                               Java



                        Serialization
creating Client with new accounts                  Client adopting statefile
elements=3                                         Client restoring accounts
   id=1                                            elements=3
   balance=100.0                                      id=1
streaming.serialize.Owner@173d14- name=bob,           balance=100.0
     taxid=111-11-1111                             streaming.serialize.Owner@174af0- name=bob,
transient dummy=Sun Aug 01 22:23:35 EDT                 taxid=111-11-1111
     1999                                          transient dummy=null
   id=2                                               id=2
   balance=200.0                                      balance=200.0
streaming.serialize.Owner@173d0f- name=larry,      streaming.serialize.Owner@174ae5- name=larry,
     taxid=222-22-2222                                  taxid=222-22-2222
transient dummy=Sun Aug 01 22:23:35 EDT            transient dummy=null
     1999                                             id=3
   id=3                                               balance=300.0
   balance=300.0                                   streaming.serialize.Owner@174af0- name=bob,
streaming.serialize.Owner@173d14- name=bob,             taxid=111-11-1111
     taxid=111-11-1111                             transient dummy=null
transient dummy=Sun Aug 01 22:23:35 EDT
v010926
     1999                                  Persistence                                         22
Client saving accounts
        Providing Manual Serialization                              Enterprise
                                                                         Java



                  Overrides
public class Account implements java.io.Serializable {
     private String id_;
     private double balance_;
     private Owner owner_;
     private transient Date dummy_; //only intialized on ctor
     private void writeObject(ObjectOutputStream out) throws IOException
    {
         System.out.println("do something to override writeObject");
         out.writeObject(id_); out.writeDouble(balance_);
         out.writeObject(owner_);
         out.writeObject(dummy_); //write transient var out anyway
     }
     private void readObject(ObjectInputStream in) throws IOException,
                                                ClassNotFoundException {
         System.out.println("do something to override readObject");
         id_ = (String) in.readObject(); balance_ = in.readDouble();
         owner_ = (Owner) in.readObject();
         dummy_ = (Date) in.readObject(); //read transient var in anyway
     }
v010926                          Persistence                           23
            Providing Manual Serialization                                                        Enterprise
                                                                                                       Java



                      Overrides
creating Client with new accounts                      Client adopting statefile
elements=3                                             Client restoring accounts
   id=1                                                do something to override readObject
   balance=100.0                                       do something to override readObject
streaming.serialize.Owner@173d14- name=bob,            do something to override readObject
      taxid=111-11-1111                                elements=3
transient dummy=Sun Aug 01 22:39:57 EDT 1999              id=1
   id=2                                                   balance=100.0
   balance=200.0                                       streaming.serialize.Owner@174ad8- name=bob,
streaming.serialize.Owner@173d0f- name=larry,                taxid=111-11-1111
      taxid=222-22-2222                                transient dummy=Sun Aug 01 22:39:57 EDT 1999
transient dummy=Sun Aug 01 22:39:57 EDT 1999              id=2
   id=3                                                   balance=200.0
   balance=300.0                                       streaming.serialize.Owner@174b19- name=larry,
streaming.serialize.Owner@173d14- name=bob,                  taxid=222-22-2222
      taxid=111-11-1111                                transient dummy=Sun Aug 01 22:39:57 EDT 1999
transient dummy=Sun Aug 01 22:39:57 EDT 1999              id=3
Client saving accounts                                    balance=300.0
do something to override writeObject                   transient dummy=Sun Aug 01 22:39:57 EDT 1999
do something to override writeObject
do something to override writeObject

v010926                                         Persistence                                             24
                  read/writeObject versus                     Enterprise
                                                                   Java



                     read/writeExternal
• read/writeObject (from java.io.Serializable)
     – declared private
     – override saving implementation for the class
     – does not need to address parent or contained members
• read/writeExternal (from java.io.Externalizable)
     –    declared non-private
     –    override saving implementation for the object
     –    needs to address parent and contained members
     –    Externalizable extends Serializable




v010926                           Persistence                       25
                                                                                Enterprise
                                                                                     Java

                       Object/RBDMS
• How do we map the following Class Model to an RDBMS
               Owner                                 Account
                          owner_               id_ : String
          name_ : String
          taxId_ : String                      balance_ : double
                          1               *




                      InterestBearingAccount                  CheckingAccount
                   rate_ : double                            checkFee_ double
                   termDays_ : int
                   minimumBalance_ : double




v010926                               Persistence                                     26
                                                                                              Enterprise
                                                                                                   Java

               Storing the Objects as Blobs
void save() throws SQLException, Exception {
  PreparedStatement pstatement = null;
  try {
     pstatement = connection_.prepareStatement("insert into accounts(id, data) values (?, ?)");
     for(int i=0; i<accounts_.length; i++) {
          pstatement.setString(1,accounts_[i].getId());
          try {
            ByteArrayOutputStream bout = new ByteArrayOutputStream();
            ObjectOutputStream ostream = new ObjectOutputStream(bout);
             ostream.writeObject(accounts_[i]);
            ostream.close();
            ByteArrayInputStream istream = new ByteArrayInputStream(bout.toByteArray());
            pstatement.setBinaryStream(2, istream, (int)bout.length());
            //pstatement.setObject(2,accounts_[i]); - for databases supporting setObject
            pstatement.execute();
            pstatement.clearParameters();
         } catch (...
      }
   }
   finally { if (pstatement != null) pstatement.close(); }
}
v010926                                      Persistence                                            27
                                                                             Enterprise
                                                                                  Java

           Restoring Objects from Blobs
void restore() throws SQLException, Exception {
  Statement statement = null;
  ResultSet rs = null;
  try {
       statement = connection_.createStatement();
       rs = statement.executeQuery("select id, data from accounts";);
       Vector accounts = new Vector();
       while (rs.next()) {
         String accountNo = rs.getString(1);
         ObjectInputStream istream = new ObjectInputStream(rs.getBinaryStream(2));
           Account account = (Account) istream.readObject();
         //Account account = (Account) rs.getObject(2);
         accounts.add(account);
         accounts_ = new Account[accounts.size()]; accounts.toArray(accounts_);
  }
  finally {
        if (rs != null) rs.close(); if (statement != null) statement.close();
  }
}
v010926                             Persistence                                    28
                                                                           Enterprise
                                                                                Java

                            Using Blobs
• Pros
     – Good encapsulation of object properties
• Cons
     – Example still allows for accidental object duplication
     – Slows database performance
          • can segment object into multiple tables and make use of lazy
            instantiation
     – Serialization brittle in the face of software changes/extended time
          • better use as a cache
          • possible use of XML or other stable marshalling forms




v010926                             Persistence                                  29
                                                                                   Enterprise
                                                                                        Java

             Horizontal Partitioning
• Each concrete class is mapped to a table
                            Owner                                 Account
                                       owner_               id_ : String
                       name_ : String
                       taxId_ : String                      balance_ : double
                                       1               *




                                   InterestBearingAccount                  CheckingAccount
                                rate_ : double                            checkFee_ double
                                termDays_ : int
                                minimumBalance_ : double




v010926                     Persistence                                                  30
                                                                                   Enterprise
                                                                                        Java

               Vertical Partitioning
• Each class is mapped to a table
                            Owner                                 Account
                                       owner_               id_ : String
                       name_ : String
                       taxId_ : String                      balance_ : double
                                       1               *




                                   InterestBearingAccount                  CheckingAccount
                                rate_ : double                            checkFee_ double
                                termDays_ : int
                                minimumBalance_ : double




v010926                     Persistence                                                  31
                                                                                   Enterprise
                                                                                        Java

                     Unification
• Each sub-class is mapped to the same table
                            Owner                                 Account
                                       owner_               id_ : String
                       name_ : String
                       taxId_ : String                      balance_ : double
                                       1               *




                                   InterestBearingAccount                  CheckingAccount
                                rate_ : double                            checkFee_ double
                                termDays_ : int
                                minimumBalance_ : double




v010926                     Persistence                                                  32
                                                                               Enterprise
                                                                                    Java

                      RDBMS Mapping
• Horizontal Partitioning                  • Vertical Partitioning (cont.)
     – entire object within one table             – no unnecessary fields in each
     – only one table required to                   table
       activate object                            – only need to search over parent
     – no unnecessary fields in the                 tables for common properties
       table                               • Unification
     – must search over multiple                  – entire object within one table
       tables for common properties               – only one table requred to
• Vertical Partitioning                             activate object
     – object spread across different             – unnecessary fields in the table
       tables                                     – all sub-types will be located in
     – must join several tables to                  a search of the common table
       activate object




v010926                             Persistence                                      33
                                                       Enterprise
                                                            Java

          Inserting Data Access Objects
           Application                   Data Access
             Object                        Object
                         Value
                         Object



            Account                     AccountDAO
                         Account
                          Value


                         Owner
                         Value

             Owner                      OwnerDAO


v010926                   Persistence                        34
                                                                        Enterprise
                                                                             Java

                                  Roles
• Application Objects
     –    Encapsulate the business rules
     –    Obtain connections
     –    Demarcate transactions
     –    Not Serializable
• Value Objects
     – Simply carry values
     – Serializable
• Data Access Objects
     – Encapsulate interaction with information source (database)
     – Designed to work with different Application Objects (e.g., no threads)
     – Not Serializable
v010926                            Persistence                                35
                                                                       Enterprise
                                                                            Java

                                  Value Object
package ejava.persistence.dao;
public OwnerValue implements Serializable {
  String name_;
  String taxId_;
  public OwnerValue(String name, String taxId) {
    name_ = name;
    taxId_ = taxId;
  }
  public OwnerValue(OwnerValue rhs) { this(rhs.name_, rhs.taxId_); }
  public String getName()             { return name_; }
  public void setName(String name)         { name_ = name; }
  public String getTaxId()           { return taxId_; }
  public void setTaxId(String taxId)     { taxId_ = taxId; }
  public String toString() {
    return "name="+name + ", taxId="+taxId_;
  }
}

v010926                                      Persistence                     36
                                                                           Enterprise
                                                                                Java

                            Data Access Object
package ejava.persistence.dao;
public class OwnerDAO {
  OwnerValue values_;
  public void insert(Connection connection, OwnerValues values) {
    Statement statement = null;
    try {
      statement = connection.createStatement();
      int rows = statement.executeUpdate(
         "insert into owner (name, taxid) values (" + values.getName() +
         ", " + values.getTaxId() + ")");
      if (rows != 1) ...
    }
    finally {
      if (statement != null) statement.close();
    }
  }
}

v010926                                         Persistence                      37
                                                                            Enterprise
                                                                                 Java

                        Application Object
package ejava.persistence.dao;

/**
  This class represents the business logic for Owners.
*/
public class Owner
{
   private OwnerValue values_;
   private static OwnerDAO ownerDAO_ = new OwnerDAO();

  public Owner() { }
  public OwnerValue getValues()       { return new OwnerValue(values_); }
  public void setValues(OwnerValues values) { values_ = values; }
  private Connection getConnection() {…}
  private void closeConnection(Connection connection) {…}

v010926                               Persistence                                 38
                                                               Enterprise
                                                                    Java

                      Application Object
public void create(OwnerValues values) throws SQLException {
   values_ = values;
   Connection connection = null;
   try {
     connection = getConnection();
     ownerDAO_.insert(connection, values_);
   }
   finally {
     closeConnection(connection);
   }
 }




v010926                              Persistence                     39
                                                   Enterprise
                                                        Java

               Application Object (cont.)
 public void remove() throws SQLException {
    Connection connection = null;
    try {
       connection = getConnection();
      ownerDAO_.remove(connection, values_);
      values_ = null;
    }
    finally {
       closeConnection(connection);
    }
  }
}




v010926                              Persistence         40
                                                             Enterprise
                                                                  Java

                    OODMBS Mapping
• No Impedance mismatch
• Class model becomes the schema for the database
• References to other objects maintained through smart
  database pointers
     – object is activated when necessary
          • usually on object access
     – object is passivated when necessary
          • usually on timeout or system resource shortage




v010926                                Persistence                 41
                                                                   Enterprise
                                                                        Java

                           Example Code
Database db = database.open(”Accounts", Database.openReadWrite);
Transaction t = transaction.begin();
try
{
   Account account = new Account(...);
   db.bind( account, ”123" );
   account.withdraw( 5.00 );
}
catch(ODMGException e ) { }
t.commit();
db.close();




v010926                               Persistence                        42

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:5
posted:7/31/2011
language:English
pages:42