db-ojb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From arm...@apache.org
Subject svn commit: r412448 - /db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/howtos/howto-use-lobs.xml
Date Wed, 07 Jun 2006 16:37:42 GMT
Author: arminw
Date: Wed Jun  7 09:37:42 2006
New Revision: 412448

URL: http://svn.apache.org/viewvc?rev=412448&view=rev
Log:
add new section, update sections

Modified:
    db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/howtos/howto-use-lobs.xml

Modified: db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/howtos/howto-use-lobs.xml
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/howtos/howto-use-lobs.xml?rev=412448&r1=412447&r2=412448&view=diff
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/howtos/howto-use-lobs.xml
(original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/howtos/howto-use-lobs.xml
Wed Jun  7 09:37:42 2006
@@ -160,7 +160,7 @@
     public Clob getClob() {return clob;}
     public void setClob(Clob clob) {this.clob = clob;}
 }
-                ]]></source>
+]]></source>
                 <p>
                     Then the mapping would look like this:
                 </p>
@@ -187,7 +187,7 @@
      jdbc-type="CLOB"
   />
 </class-descriptor>
-                ]]></source>
+]]></source>
                 <p>
                     More information about how to map columns in OJB see
                     <a href="site:repository">repository section</a>.
@@ -224,13 +224,13 @@
 public Clob newClob(Reader reader);
 public Clob newClob(String value);
 public Clob newClob();
-                ]]></source>
+]]></source>
                 <p>
                     To access this class use the service method in <code>PersistenceBroker</code>
class:
                 </p>
                 <source><![CDATA[
 LobHelper lh = broker.serviceLobHelper();
-                ]]></source>
+]]></source>
                 <p>
                     Assume we want to insert an object of class <code>LobObject</code>
(described in the
                     <a href="#lobMapping">example above</a>). The LOB content
is an image file.
@@ -246,7 +246,7 @@
 obj.setBlob(b);
 broker.store(obj);
 broker.commitTransaction();
-                ]]></source>
+]]></source>
                 <p>
                     The <code>InputStream</code> <em>in</em> will
normally be closed by the jdbc-driver.
                 </p>
@@ -275,34 +275,40 @@
 // create new object
 LOBTest.LobObject obj = new LobObject();
 // insert new object to get a valid PK
-broker.store(obj);
+broker.store(obj, ObjectModification.INSERT);
+
 // get the current Connection
 Connection con = broker.serviceConnectionManager().getConnection();
 Statement stmt = con.createStatement();
-// use database specific function to create an empty LOB
+// use database specific function to create an empty LOB on DB
 stmt.execute ("UPDATE BLOB_TEST SET BLOB_VALUE_ = empty_blob() WHERE ID = " + obj.getId());
 stmt.close();
 
-// Lookup identity
-Identity oid = broker.serviceIdentity().buildIdentity(obj);
-// remove object from cache to force DB roundup
-broker.removeFromCache(oid);
-// lookup from DB
-obj = (LobObject) broker.getObjectByIdentity(oid);
-
+// Refresh LOB field to get the empty LOB-locator
+broker.serviceLobHelper().refreshLob(obj);
 Blob blob = obj.getBlob();
+// writing to oracle Blob-OutputStream, this writes directly to
+// the database
 OutputStream outstream = blob.setBinaryStream(1);
 byte[] buffer = new byte[100];
 int length = -1;
 while ((length = instream.read(buffer)) != -1)
 outstream.write(buffer, 0, length);
+// in/out-stream cleanup
 instream.close();
 outstream.close();
-// writing to oracle Blob OutputStream write directly to
-// the database, thus no need to store/update the LobObject instance
-// broker.store(obj);
+// this method call help to synchronize the cache and
+// will update all non-PK, non LOB fields.
+broker.store(obj, ObjectModification.UPDATE);
+// mandatory, commit transaction
 broker.commitTransaction();
-                    ]]></source>
+]]></source>
+                    <p>
+                        The last <code>broker.store(obj)</code> call will not
update the LOB field again,
+                        because Oracle java-LOB's updates made directly to the LOB and OJB
will skip
+                        these fields on persistence capable object update calls (because
Oracle database
+                        metadata return <em>locatorsUpdateCopy</em> false - see
JDBC 3.0 section 16.3.3).
+                    </p>
                     <p>
                         More detailed information about
                         <a href="site:connection/obtain-connection">
@@ -317,6 +323,87 @@
             </section>
 
 
+            <anchor id="lifecycle"/>
+            <section>
+                <title>LOB object lifecycle and wrapper classes</title>
+                <p>
+                    In all requested <em>persistence capable objects</em> with
LOB fields OJB wraps the
+                    <code>java.sql.Blob</code> and <code>java.sql.Clob</code>
instances (provided by the jdbc-driver)
+                    with wrapper classes (see class <a href="ext:blob-handle"><code>BlobHandle</code></a>
and
+                    <a href="ext:clob-handle"><code>ClobHandle</code></a>).
These wrapper classes restrict the
+                    life of the wrapped LOB instances independent from the used database
(except when using
+                    <a href="#reportQueries">Report Queries</a> to query LOB
content).
+                </p>
+                <p>
+                    LOB fields behavior is different from <em>normal</em> fields.
+                    LOB fields will become <em>invalid</em> when
+                </p>
+                <ul>
+                    <li>
+                        the current transaction commits or rollback
+                    </li>
+                    <li>
+                        the current <code>PersistenceBroker</code>
+                        instance was closed
+                    </li>
+                </ul>
+                <p>
+                    The access of LOB content is only valid within an active
+                    transaction else a <code>LobException</code> will be thrown.
To access LOB content
+                    first begin the tx and then lookup/query the persistent object:
+                </p>
+                <source><![CDATA[
+// mandatory to start a tx
+broker.beginTransaction();
+// query/lookup object with LOB content
+LobObject obj = (LobObject) broker.getObjectByQuery(...);
+Blob b = obj.getBlob();
+// access LOB
+....
+broker.commitTransaction();
+]]></source>
+                <p>
+                    If you query the <code>LobObject</code> without running tx
it's not allowed to access
+                    the LOB content.
+                </p>
+                <p>
+                    If the persistent object already exists from a previous tx you have to
+                    <a href="#refreshLobs">refresh the LOB instances</a> within
the current transaction.
+                </p>
+
+
+                <anchor id="unwrap"/>
+                <section>
+                    <title>Excursus: Access wrapped LOB content</title>
+                    <p>
+                        All LOB content (of persistence capable objects) provided by the
jdbc-driver
+                        (e.g. <code>java.sql.Blob</code> and <code>java.sql.Clob</code>
instances) is wrapped with
+                        OJB specific classes.
+                    </p>
+                    <p>
+                        It is possible to access the jdbc-driver specific LOB implementation
instances using
+                        methods to get the innermost LOB object - after cast to wrapper class
(these classes
+                        are described in <a href="#lifecycle">section above</a>).
For the
+                        <a href="#lobMapping">example mapping</a> it would look
like this
+                        (for <code>java.sql.Blob</code> and <code>java.sql.Clob</code>
instances):
+                </p>
+                <source><![CDATA[
+// get the wrapped LOB instance from the
+// persistence capable object
+Blob b = lobObject.getBlob();
+// now cast to wrapper class and lookup
+// innermost Blob instance
+Blob realBlob = ((BlobHandle) b).getBlob();
+
+Clob c = lobObject.getClob();
+// now cast to wrapper class and lookup
+// innermost Clob instance
+Clob realClob = ((ClobHandle) c).getClob();
+]]></source>
+                </section>
+            </section>
+
+
             <anchor id="queryLobs"/>
             <section>
                 <title>Querying LOB content</title>
@@ -325,15 +412,24 @@
                     compared to objects without. All about how to query objects in OJB you
can find
                     in the <a href="site:query">query-</a> and api-guides.
                 </p>
-            </section>
-
-
-            <anchor id="lifecycle"/>
-            <section>
-                <title>Lifecycle of LOB fields</title>
                 <p>
-                    
+                    The only difference is that the access of LOB-fields (<code>java.sql.Blob</code>
+                    and <code>java.sql.Clob</code> fields in persistence capable
objects) is only valid within
+                    active transactions - see <a href="#lifecycle">LOB content lifecycle</a>
                 </p>
+
+                <anchor id="reportQueries"/>
+                <section>
+                    <title>LOB content via <a href="site:query/report-queries">Report
Query</a></title>
+                    <p>
+                        Using <a href="site:query/report-queries">Report Query</a>
to lookup LOB content
+                        will return the <code>java.sql.Blob</code> and <code>java.sql.Clob</code>
instances
+                        provided by the jdbc-driver - in contrast to persistence capable
objects with LOB content
+                        OJB <strong>do not wrap</strong> these instances with
specific
+                        <a href="#lifecycle">wrapper objects</a>.
+                    </p>
+                </section>
+
             </section>
 
 
@@ -341,26 +437,83 @@
             <section>
                 <title>Refresh LOB's</title>
                 <p>
-                    ########## to be written #########
+                    As said in the <a href="#lifecycle">lifecycle section</a>
the access of LOB content in
+                    persistence capable objects is only valid in context of a transaction
and only till
+                    commit/rollback or close of the associated <code>PersistenceBroker</code>
instance.
+                    <br/>
+                    If the persistent object already exists from a previous tx you have to
refresh the
+                    LOB instances within the current transaction using method
+                    <code>LobHelper.refreshLob(...)</code>:
                 </p>
+                <source><![CDATA[
+// existing object
+LobObject obj = ...;
+// mandatory to start a tx
+broker.beginTransaction();
+// refresh the LOB content
+broker.serviceLob().refreshLob(obj);
+Blob b = obj.getBlob();
+// access LOB
+....
+broker.commitTransaction();
+]]></source>
 
+                
                 <anchor id="autoRefresh"/>
                 <section>
-                    <title>Enable automatic refresh of LOB content</title>
+                    <title>Automatic LOB refresh</title>
                     <p>
-
+                        By default OJB automatically refresh the LOB-content of cached persistent
objects on
+                        request of objects by query or identity lookup.
                     </p>
+                    <source><![CDATA[
+# LOB-locator objects (Blob and Clob fields in persistence capable objects) are only
+# valid as long as the current PersistenceBroker transaction is active. After commit or
+# rollback the LOB-object will be invalidated and before next access to the LOB-locator
+# object it must be refreshed. Cached persistent objects with LOB-content need refresh
+# too. OJB will automatically refresh all objects requested by query or identity lookup.
+# Set this property to 'false' to disable this service.
+LobAutoRefresh=true
+]]></source>
                 </section>
 
             </section>
 
-
-            <anchor id="updateLobs"/>
+            <anchor id="caching"/>
             <section>
-                <title>Update LOB's</title>
+                <title>Caching and LOB fields</title>
                 <p>
-                    ########## to be written #########
+                    OJB wraps all LOB fields of persistence capable objects to allow caching
of
+                    these objects. But dependend on the used <a href="site:object-cache">object
cache</a>
+                    you have to take care:
                 </p>
+                <ul>
+                    <li>
+                        <p><a href="site:object-cache/session">session cache</a></p>
+                        <p>
+                            Save for use, because each <code>PersistenceBroker</code>
instance use it's
+                            own cache (no shared cache) and the cache will be cleared when
broker is closed.
+                        </p>
+                    </li>
+                    <li>
+                        <p><a href="site:object-cache/two-level">two-level cache</a></p>
+                        <p>
+                            Save for use, the first level cache is used within transactions
and
+                            the shared second level cache is based on field copies. All LOB
fields
+                            will be copied using placeholder.
+                        </p>
+                    </li>
+                    <li>
+                        <p><a href="site:object-cache/shared">shared cache</a></p>
+                        <p>
+                            Read carefully the documentation about this cache implementation.
It's
+                            important to avoid concurrent modification of objects by different
+                            sessions/threads. Also concurrent read of the same object (with
LOB content)
+                            will cause problems, because the LOB content can only be assigned
to one
+                            <code>PersistenceBroker</code> at the same time.
+                        </p>
+                    </li>
+                </ul>
             </section>
 
         </section>



---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Mime
View raw message