530 likes | 699 Views
Objektorienteret Middleware (OOMI). Persistence. Goal with todays lesson. After these 2x35 minutes you will be: Comfortable with the expression “persistence”, and how it relates to Distributed Systems Knowledgeable about different strategies for obtaining persistence for Distributed Systems
E N D
Objektorienteret Middleware (OOMI) Persistence
Goal with todays lesson • After these 2x35 minutes you will be: • Comfortable with the expression “persistence”, and how it relates to Distributed Systems • Knowledgeable about different strategies for obtaining persistence for Distributed Systems • You will not: • Be an expert on persistence, as this is a huge area in itself
Outline • Plenum – experince with persistent datastorage • Principles of Persistence • Datastore Technology for Persistence • Files • Relational Databases • Object Databases • Exemplified OR-mapping with EJB
Experience with Persistent datastorage • To establish a picture of your knowledge • What kind of persistent datastorage do you know? • What experience do you have in using it with programming languages? • What problems did you face – and how did you solve them?
What is Persistence? • Persistence is the ability of an object to survive the lifetime of the process in which it resides. • Persistence is relevant for stateful server objects. • What is State? • State = object instance attributes – private & public • Not methods • RMI & CORBA activation/deactivation • The state needs to be retained between object deactivation and object activation • Why?
How to achieve Persistence? • Storing object state on persistent datastore before de-activation • Upon activation, load object state from persistent datastore • As we shall see in RMI & CORBA • Persistent storage can be obtained by? • File system (Hard Drive, Disk-on-Chip, Flash Memory) • embedded systems with a disk storage • Relational Database • All from embedded, to desktop and enterprise servers (most widely used is SQL servers) • Object-Database • no widespread support yet
Transparency of Persistence • Persistence should be transparent to users and designers of client objects Client Objects Datastore Objects Server Objects Client Interface Persistence Interface
Persistence Concepts Object = row in RDBMS table C++/Java object or class Storage Storage Home Objects Incarnation C++/Java object Datastore Sessions Storage Homes RDBMS Server Storage Object RDBMS Table Incarnation C++/Java object
Datastore Technology • Persistence can be implemented using • Files • CORBA Externalization • Java Serialization • Structured Storage in COM • Relational Databases • Object Relational Mappings • JDBC/ODBC • Oracle, IBM DB2, Microsoft SQL Server & Access, MySQL • Object Databases
How to obtain persistence? • Roll your own persistence • SOAP, RMI • For Java – use JDBC for RDBMS, serialization for filesystems • CORBA Externalization for filesystems • COM Serialization or Structured Storage • Possible to construct your own framework (e.g. ROAD) • Use a standard service • CORBA Persistence service (PSS) • COM Persistence service • Enterprise Java Beans • May still be necessary to obtain persistence manually
Externalization in CORBA • Technique to • write composite objects into a byte stream • load composite objects from a byte stream • Byte stream can then be written to/read from the file system • Supported by several CORBA products • Also used to store Java objects
Java Serialization • Transforms Java objects into stream • Follows all referenced Java objects • Stream can be written onto a file to achieve persistence • Objects must implement Serializable • Attributes that need not be made persistent can be declared as transient in the class definition
Example of using Serialization for RMI • http://java.sun.com/j2se/1.3/docs/guide/rmi/activation/activation.4.html • Class: • public class MyPersistentClass extends Activatable • This Activatable class will • Restore its State upon activation (if the file persistentObjectStore.ser exist) • Save its State after a new transaction is registered • This could also have been done utilizing an RDBMS
private Vector transactions; private File holder; public MyPersistentClass(ActivationID id, MarshalledObject data) throws RemoteException, ClassNotFoundException, java.io.IOException { // Register the object with the activation system // then export it on an anonymous port super(id, 0); // Extract the File object from the MarshalledObject that was // passed to the constructor holder = (File)data.get(); if (holder.exists()) { // Use the MarshalledObject to restore my state this.restoreState(); } else { transactions = new Vector(1,1); transactions.addElement("Initializing transaction vector"); } } CONSTRUCTOR of MyPersistentClass Find complete example and tutorial at: http://java.sun.com/j2se/1.3/docs/ guide/rmi/activation/activation.4.html Every time a passivated object is called, the constructor is called as the rmid daemon Instantiates it to activate – and here it is checked whether the File exist – or not. If it does exist, then its State is restored
public Vector calltheServer(Vector v) throws RemoteException { int limit = v.size(); for (int i = 0; i < limit; i++) { transactions.addElement(v.elementAt(i)); } // Save this object's data out to file // this.saveState(); return transactions; } private void restoreState() throws IOException, ClassNotFoundException { File f = holder; FileInputStream fis = new FileInputStream(f); ObjectInputStream ois = new ObjectInputStream(fis); transactions = (Vector)ois.readObject(); ois.close(); } private void saveState() { try { File f = holder; FileOutputStream fos = new FileOutputStream(f); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(getTransactions()); oos.close(); } catch (Exception e) { throw new RuntimeException("Error saving vector of data"); } } Find complete example and tutorial at: http://java.sun.com/j2se/1.3/docs/ guide/rmi/activation/activation.4.html Using simpel Java Serilization To obtain perstistence
Persistence Interfaces in COM <<Interface>> IUnknown <<Interface>> IPersist + GetClassID() <<Interface>> <<Interface>> <<Interface>> IPersistStorage IPersistStream IPersistFile + IsDirty() + IsDirty() + IsDirty() + InitNew() + Load() + Load() + Load() + Save() + Save() + Save() + GetSizeMax() + SaveCompleted() + SaveCompleted() + GetCurFile() + HandsOffStorage()
Problems with File-based Persistence • Mapping to Files can be inefficient for large composite objects • Finder methods diffuclt to develop • Naming & File search difficult • File systems only have crude support for concurrency control • File systems lack support for fault-tolerance (transactions) • Application specific code needed for every persistent class
Relational Database • Relational Database Management Systems (RDBMSs) Examples: • Oracle • DB2 • Microsoft SQL Server • Sybase • Microsoft Access • MySQL (freeware) • PostGree DB (freeware)
Mapping to RDBMSs • Relational database schemas consist of sets of tables • Define a table for each type • In each table create • primary key for object identifier • a column for each attribute of the object • mapping of middleware atomic types to primitive types supported by RDMBS • secondary keys for object references • Resolve inheritance statically • This and other problems -> the OR impedance mismatch
Embedding Queries into Programs • Pure Embedded SQL • Macros to embed queries into programs • RDBMS provides processor to expand macros • API to traverse queries • Not standardized • Open Database Connectivity - ODCB (Microsoft) • Standardized API for RDBMS Access available on all Microsoft Platforms • Java Database Connectivity – JDCB (Sun) • Standardized RDBMS Access from Java
Issues with mapping • Does this mean that we should figure out for ourselfes how to obtain the OR-mapping? • No • Frameworks available • CORBA PSS, COM persistence, EJB for Java • JDBC/ODBC is at a low level – but very feasible • Torque/Turbine project freeware • JDO maps to XMI • In the following EJB will be presented
Enterprise JavaBeans (EJBs) • Standard server-side component model for Java Enterprise Applications • security • resource pooling • persistence • concurrency • transactional integrity • Has nothing to do with “JavaBeans” • JavaBeans designed for intra-process purposes • GUIs • non-visual widgets • Enterprise Java Beans (EJB) designed for inter-process purposes
EJBs (cont.) • Java • platform independence • “write once, run anywhere” • EJB components • platform/implementation independence • write once, run in any Application Server complying with the EJB spec • J2EE reference implementation • Oracle’s Application Server (OAS) • IBM’s Websphere • BEA’s Weblogic Server and Weblogic Enterprise • Sybase’s EAServer • Open Source – JBoss (see links)
EJB Architecture • Interfaces and Classes • beans • entity bean (maps perfectly to the “Entity stereotype” • session beans (no primary key – maps to “Control”) • Stateless session bean • Stateful session bean • GUI? JSP/Servlet or Java Application • primary key (implemented in a class) • home interface (local and remote) • EJB object interface (local and remote) • Container / Application Server
Bean Types • Entity beans • models persistent state - this state is maintained through all method and server invocations • nouns of the domain • real world objects (e.g. Owner, Account, Transaction) • Session beans • models non-persistent state - this state will be lost between method invocations (stateless session) or server invocations (Stateful session) • manage tasks performed on behalf of a single client (e.g. Teller, Monthly Statement) • contains the business processes in which to use entity beans • manages actions that may cross entity beans or go outside the concern of an entity bean • e.g. Teller may authenticate the user and transfer funds between accounts • e.g. Statement may include transactions from multiple accounts
Bean Usage Maps to domain model (Entity classes) • Entity beans • model state maintained across all client interactions • represent a row of data in a database • Session beans • model business process being performed by a single client involving one or more entity beans • it extends the actions of the client into the server • simplifies the actions programmed by the client • limits the number of distributed calls required between the client and the entity beans • limits the number of stubs that have to be loaded by the client • are not persisted to a database Maps to Use Case model (Control classes)
Persistence Concepts in EJB Storage Storage Home Objects Incarnation Datastore Sessions Storage Homes Storage Object Incarnation
State Management • State synchronization methods • ejbLoad • ejbStore • Resource Management methods • ejbActivate • ejbPassivate
Entity Bean Types • Bean can have total control over loading and storing from database • Bean Managed Persistence (BMP) • Container can take over this responsibility • Container Managed Persistence (CMP) • Still need to define an OR mapping in admin tool • This is the same in CORBA PSS • Specialized Implementations • Legacy applications such as CICS • When to choose what? • Well – start out with CMP if possible, and then migrate code as performance issues pops up during testing
Bean Manged Perstistence • Have to handle all database interaction • except transactions (more of this next time) • ejbLoad() and ejbStore() called when bean instance state must be synchronized with database • ejbActivate() and ejbPassivate() called when bean is moved between the ready state and pooled state
Implement a BMP Entity Bean package java.examples.ejb.entity.bean; import javax.ejb.EntityBean; import javax.ejb.EntityContext; … public class BookBMP extends BookEJB { private DataSource dataSource_; private EntityContext ctx_; … Additional setup of database connections needed – some are done in the configuration tool • Important features: Entity beans always implement the following event handles: • ejbCreate: inseret • ejbRemove: delete • ejbLoad: select • ejbStore: update • ejbFindByPrimaryKey: select • And more can be implemented: • ejbFindBooksByAuthor: select
Implement DB Insertion public String ejbCreate(String id, String title, String author, String topic) { super.ejbCreate(id, title, author, topic); Connection conn = null; PreparedStatement pstatement = null; try { conn = dataSource_.getConnection(); pstatement=conn.prepareStatement("insert into Book (id, title, author, topic)"+ ” values (?, ?, ?, ?)"); pstatement.setString(1,id_); pstatement.setString(2,title_); pstatement.setString(3,author_); pstatement.setString(4,topic_); pstatement.execute(); return id_; } catch(SQLException ex) { throw new EJBException(ex); } finally { … } } BookBMP OR mapping
Implement DB Load public void ejbLoad() { Connection conn = null; PreparedStatement pstatement = null; ResultSet rs = null; try { conn = dataSource_.getConnection(); pstatement = conn.prepareStatement( "select id, title, author, topic from Book " + "where id = ?"); pstatement.setString(1, (String)ctx_.getPrimaryKey()); rs = pstatement.executeQuery(); if (rs.next()) { id_ = rs.getString("id"); title_ = rs.getString("title"); author_ = rs.getString("author"); topic_ = rs.getString("topic"); super.ejbLoad(); } else { throw new EJBException("unable to locate row"); } } catch(SQLException ex) { throw new EJBException(getText(ex)); } finally { … } ...
Implement DB Store public void ejbStore() { Connection conn = null; PreparedStatement pstatement = null; try { super.ejbStore(); conn = dataSource_.getConnection(); pstatement = conn.prepareStatement( "update Book set title=?, author=?, topic=? " + "where id = ?"); pstatement.setString(1,title_); pstatement.setString(2,author_); pstatement.setString(3,topic_); pstatement.setString(4,id_); pstatement.executeUpdate(); } catch(SQLException ex) { throw new EJBException(getText(ex)); } finally { … } }
Implement DB Remove public void ejbRemove() { Connection conn = null; PreparedStatement pstatement = null; try { super.ejbRemove(); conn = dataSource_.getConnection(); pstatement = conn.prepareStatement("delete from Book " + "where id = ?"); pstatement.setString(1, (String)ctx_.getPrimaryKey()); pstatement.executeUpdate(); } catch(SQLException ex) { throw new EJBException(getText(ex)); } finally { … } }
Implement Finders public String ejbFindByPrimaryKey(String pk) throws FinderException { Connection conn = null; PreparedStatement pstatement = null; ResultSet rs = null; try { conn = dataSource_.getConnection(); pstatement = conn.prepareStatement("select id from Book " + "where id = ?"); pstatement.setString(1, pk); rs = pstatement.executeQuery(); if (rs.next()) { return rs.getString("id"); } else { throw new ObjectNotFoundException(pk + " no found"); } } catch(SQLException ex) { throw new EJBException(getText(ex)); } finally {... } }
Implement Finders (cont.) public Collection ejbFindAll() throws FinderException { Connection conn = null; PreparedStatement pstatement = null; ResultSet rs = null; try { Vector pKeys = new Vector(); conn = dataSource_.getConnection(); pstatement = conn.prepareStatement("select id from Book "); rs = pstatement.executeQuery(); while (rs.next()) { pKeys.add(rs.getString("id")); } return pKeys; } catch(SQLException ex) {throw new EJBException(getText(ex)); } finally {... } }
1 // Fig. 31.20: GuestBean.java 2 // JavaBean to store data for a guest in the guest book. 3 package com.deitel.advjhtp1.jsp.beans; 4 5 public class GuestBean { 6 private String firstName, lastName, email; 7 8 // set the guest's first name 9 public void setFirstName( String name ) 10 { 11 firstName = name; 12 } 13 14 // get the guest's first name 15 public String getFirstName() 16 { 17 return firstName; 18 } 19 20 // set the guest's last name 21 public void setLastName( String name ) 22 { 23 lastName = name; 24 } 25 26 // get the guest's last name 27 public String getLastName() 28 { 29 return lastName; 30 } 31 32 // set the guest's email address 33 public void setEmail( String address ) 34 { 35 email = address; This is another way of using JDBC access to a RDBMS.It consists of two elements, the JavaBean (code to left is a GuestBean), and a DataBean (GuestDataBean).
36 } 37 38 // get the guest's email address 39 public String getEmail() 40 { 41 return email; 42 } 43 } GuestBean.java
Defines the database driver, URL, and SQL statements. 1 // Fig. 31.21: GuestDataBean.java 2 // Class GuestDataBean makes a database connection and supports 3 // inserting and retrieving data from the database. 4 package com.deitel.advjhtp1.jsp.beans; 5 6 // Java core packages 7 import java.io.*; 8 import java.sql.*; 9 import java.util.*; 10 11 public class GuestDataBean { 12 private Connection connection; 13 private PreparedStatement addRecord, getRecords; 14 15 // construct TitlesBean object 16 public GuestDataBean() throws Exception 17 { 18 // load the Cloudscape driver 19 Class.forName( "COM.cloudscape.core.RmiJdbcDriver" ); 20 21 // connect to the database 22 connection = DriverManager.getConnection( 23 "jdbc:rmi:jdbc:cloudscape:guestbook" ); 24 25 getRecords = 26 connection.prepareStatement( 27 "SELECT firstName, lastName, email FROM guests" 28 ); 29 30 addRecord = 31 connection.prepareStatement( 32 "INSERT INTO guests ( " + 33 "firstName, lastName, email ) " + 34 "VALUES ( ?, ?, ? )" 35 ); GuestDataBean.javaSet up database
Obtain the guest list from the database. Return each guest in a bean. 36 } 37 38 // return an ArrayList of GuestBeans 39 public List getGuestList() throws SQLException 40 { 41 List guestList = new ArrayList(); 42 43 // obtain list of titles 44 ResultSet results = getRecords.executeQuery(); 45 46 // get row data 47 while ( results.next() ) { 48 GuestBean guest = new GuestBean(); 49 50 guest.setFirstName( results.getString( 1 ) ); 51 guest.setLastName( results.getString( 2 ) ); 52 guest.setEmail( results.getString( 3 ) ); 53 54 guestList.add( guest ); 55 } 56 57 return guestList; 58 } 59 60 // insert a guest in guestbook database 61 public void addGuest( GuestBean guest ) throws SQLException 62 { 63 addRecord.setString( 1, guest.getFirstName() ); 64 addRecord.setString( 2, guest.getLastName() ); 65 addRecord.setString( 3, guest.getEmail() ); 66 67 addRecord.executeUpdate(); 68 } 69 70 // close statements and terminate database connection GuestDataBean.javaDatabase access methods
71 protected void finalize() 72 { 73 // attempt to close database connection 74 try { 75 getRecords.close(); 76 addRecord.close(); 77 connection.close(); 78 } 79 80 // process SQLException on close operation 81 catch ( SQLException sqlException ) { 82 sqlException.printStackTrace(); 83 } 84 } 85 } GuestDataBean.javaClose database
Calls the guestData Bean to write this new guest into the address book. The forward the client to the guestBookView JSP. 71 <input type ="text"name ="email" /> 72 </td> 73 </tr> 74 75 <tr> 76 <td colspan ="2"> 77 <input type ="submit" 78 value = "Submit"/> 79 </td> 80 </tr> 81 </table> 82 </form> 83 84 <% // continue scriptlet 85 86 } // end if 87 else { 88 guestData.addGuest( guest ); 89 90 %><%-- end scriptlet to insert jsp:forward action --%> 91 92 <%-- forward to display guest book contents --%> 93 <jsp:forward page ="guestBookView.jsp"/> 94 95 <% // continue scriptlet 96 97 } // end else 98 99 %><%-- end scriptlet --%> 100 </body> 101 102 </html> Example of usage of the JavaBean/Databean in JSPGuestBookLogin.jspAdd new guest to book
RDBMS JDBC DataBean / JavaBean • This may be better suited for WebServices / RMI • You may also employ SQL directly in your Servant objects • Also see: http://db.apache.org/torque/torque-301/tutorial/index.html on how to use Torque
Using the Torque framework Excerpt from tutorial – defining the Schema … <table name="author" description="Author Table"> <column name="author_id" required="true" primaryKey="true" type="INTEGER" description="Author Id"/> <column name="first_name" required="true" type="VARCHAR" size="128" description="First Name"/> <column name="last_name" required="true" type="VARCHAR" size="128" description="Last Name"/> </table> </database> Excerpt from tutorial – sample code Publisher addison = new Publisher(); addison.setName("Addison Wesley Professional"); addison.save(); Author bloch = new Author(); bloch.setFirstName("Joshua"); bloch.setLastName("Bloch"); bloch.save();