You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-dev@db.apache.org by ar...@apache.org on 2006/05/02 02:30:26 UTC

svn commit: r398754 - in /db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs: ./ docu/ docu/guides/ docu/howtos/

Author: arminw
Date: Mon May  1 17:30:24 2006
New Revision: 398754

URL: http://svn.apache.org/viewcvs?rev=398754&view=rev
Log:
add first part of LOB howto revision + many minor doc updates

Modified:
    db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/faq.xml
    db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/guides/pb-guide.xml
    db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/guides/query.xml
    db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/guides/repository.xml
    db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/guides/sequencemanager.xml
    db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/howtos/howto-use-lobs.xml
    db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/howtos/summary.xml
    db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/site.xml

Modified: db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/faq.xml
URL: http://svn.apache.org/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/faq.xml?rev=398754&r1=398753&r2=398754&view=diff
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/faq.xml (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/faq.xml Mon May  1 17:30:24 2006
@@ -1028,6 +1028,17 @@
             </answer>
         </faq>
 
+        <faq id="lobs">
+            <question>
+                How to use LOB's with OJB?
+            </question>
+            <answer>
+                <p>
+                    Please refer to OJB's <a href="site:use-lobs">LOB's howto</a>.
+                </p>
+            </answer>
+        </faq>
+
         <faq id="lookupPB">
             <question>
                 How to lookup <code>PersistenceBroker</code> instances?
@@ -1035,6 +1046,17 @@
             <answer>
                 <p>
                     Please refer to <a href="site:pb-guide/lookup-pb">PB-guide</a>.
+                </p>
+            </answer>
+        </faq>
+
+        <faq id="detectLeak">
+            <question>
+                How to find <code>PersistenceBroker</code> leaks?
+            </question>
+            <answer>
+                <p>
+                    Please refer to <a href="site:pb-guide/detect-leak">PB-guide</a>.
                 </p>
             </answer>
         </faq>

Modified: db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/guides/pb-guide.xml
URL: http://svn.apache.org/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/guides/pb-guide.xml?rev=398754&r1=398753&r2=398754&view=diff
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/guides/pb-guide.xml (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/guides/pb-guide.xml Mon May  1 17:30:24 2006
@@ -237,6 +237,35 @@
                 </note>
             </section>
 
+            <anchor id="detect-leak"/>
+            <section>
+                <title>How to find <code>PersistenceBroker</code> leaks</title>
+                <p>
+                    As explained in the <a href="site:pb-tutorial">PB-Tutorial</a> it's very important to close
+                    all used <code>PersistenceBroker</code> instance after use. OJB is able to detect unclosed
+                    <code>PersistenceBroker</code> instances if they are garbage collected. By default OJB will
+                    log a warning about a unclosed broker instance ("broker leak") and close the instance
+                    internally.
+                </p>
+                <p>
+                    But additionally OJB supports a development flag 'brokerLeakDetection' in
+                    <a href="ext:ojb.properties">OJB.properties</a> file. If enabled OJB will log an error
+                    with the full caller stack trace for all unclosed broker instances on garbage collector
+                    run.
+                </p>
+                <source><![CDATA[
+brokerLeakDetection=true
+                ]]></source>
+                <note>
+                    The leak detection is costly, so take care to disable this property in production environments.
+                </note>
+                <p>
+                    To detect all broker leaks it's important that the garbage collector runs before the
+                    JVM exit. So it's recommended (while development) to run the garbage collector manually
+                    before the JVM exit.
+                </p>
+            </section>
+
         </section>
 
     </body>

Modified: db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/guides/query.xml
URL: http://svn.apache.org/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/guides/query.xml?rev=398754&r1=398753&r2=398754&view=diff
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/guides/query.xml (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/guides/query.xml Mon May  1 17:30:24 2006
@@ -642,6 +642,15 @@
             </section>
 
 
+            <anchor id="query-by-identity"/>
+            <section>
+                <title>Lookup object by <code>Identity</code> (primary key)</title>
+                <p>
+                    See <a href="site:pb-tutorial/find-by-pk">lookup object by <code>Identity</code> here</a>.
+                </p>
+            </section>
+
+
             <anchor id="report-queries"/>
             <section>
                 <title>Report Queries</title>
@@ -680,7 +689,8 @@
 Criteria crit = new Criteria();
 Collection results = new Vector();
 ReportQueryByCriteria q = QueryFactory.newReportQuery(ProductGroup.class, crit);
-q.setAttributes(new String[] { "groupName", "sum(allArticlesInGroup.stock)", "sum(allArticlesInGroup.price)" });
+q.setAttributes(new String[] {
+    "groupName", "sum(allArticlesInGroup.stock)", "sum(allArticlesInGroup.price)" });
 q.addGroupBy("groupName");
 
 Iterator iter = broker.getReportQueryIteratorByQuery(q);

Modified: db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/guides/repository.xml
URL: http://svn.apache.org/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/guides/repository.xml?rev=398754&r1=398753&r2=398754&view=diff
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/guides/repository.xml (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/guides/repository.xml Mon May  1 17:30:24 2006
@@ -144,10 +144,17 @@
                     </p>
                     <p>
                         The <em>isolation-level</em> attribute defines the default locking isolation level used
-                        by OJB's <a href="site:lock-manager/pessimistic-locking">pessimistic locking</a> api. All jdbc-connection-descriptor or class-descriptor
+                        by OJB's <a href="site:lock-manager/pessimistic-locking">pessimistic locking</a> api. All
+                        <code>jdbc-connection-descriptor</code> or <code>class-descriptor</code>
                         that do not define a specific isolation level will use this.
-                        <br/>Note: This does NOT touch the jdbc-level of the connection.
+                        <br/>
+                        If undefined or "empty string" is set OJB will use a default isolation-level.
                     </p>
+                    <note>
+                        The <em>isolation-level</em> does not touch the jdbc-connection isolation level. It's completely
+                        independend from the database connection setting and only important when
+                        <a href="site:lock-manager/pessimistic-locking">pessimistic locking</a> was used.
+                    </note>
                     <p>
                         The
                         <em>proxy-prefetching-limit</em>
@@ -1060,8 +1067,10 @@
                     attribute is of the XML type ID there can only be one <em>class-descriptor </em> per class.
                 </p>
                 <p>
-                    The <em>isolation-level</em> attribute defines the locking isolation level of the
-                    specified class (used by OJB's <a href="site:lock-manager/pessimistic-locking">pessimistic locking</a> api).
+                    The <em>isolation-level</em> attribute defines the locking isolation level of the specified class
+                    (used by OJB's <a href="site:lock-manager/pessimistic-locking">pessimistic locking</a> api).
+                    Set "empty String" or skip attribute to use (the global) isolation-level defined on
+                    "descriptor-repository" level.
                 </p>
                 <note>
                     The <em>isolation-level</em> does not touch the jdbc-connection isolation level. It's completely

Modified: db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/guides/sequencemanager.xml
URL: http://svn.apache.org/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/guides/sequencemanager.xml?rev=398754&r1=398753&r2=398754&view=diff
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/guides/sequencemanager.xml (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/guides/sequencemanager.xml Mon May  1 17:30:24 2006
@@ -541,7 +541,7 @@
                         </tr>
                         <tr>
                             <td>seq.cache</td>
-                            <td>&gt;= 2</td>
+                            <td>&gt;= 2, (0)</td>
                             <td>
                             Database sequence specific property.<br/>
                             Specifies how many values of the sequence Oracle

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/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/howtos/howto-use-lobs.xml?rev=398754&r1=398753&r2=398754&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 Mon May  1 17:30:24 2006
@@ -22,75 +22,382 @@
         <title>HOWTO - Work with LOB Data Types</title>
         <authors>
             <person name="Torsten Schlabach" email="tschlabach@gmx.net"/>
+            <person name="Armin Waibel" email="arminw@apache.org"/>
         </authors>
     </header>
 
     <body>
+        <anchor id="introduction"/>
+        <section>
+            <title>Introduction</title>
+            <p>
+                In a lot of applications there is a need to store large text or binary objects into the database.
+                The definition of large usually means that the object's size is beyond the maximum length of
+                a character field. For example in Oracle this means the objects to be stored can grow
+                to &gt; 4 KB each.
+            </p>
+
+            <p>
+                Depending on the application you are developing your "large objects" may either be in the
+                range of some Kilobytes (for example when storing text-only E-Mails or regular XML documents),
+                but they may also extend to several Megabytes (thinking of any binary data such as larger
+                graphics, PDFs, videos, etc.).
+            </p>
+
+            <p>
+                In practice, the interface between your application and the database used for fetching and
+                storing of your "large objects" needs to be different depending on the expected size.
+                While it is probably perfectly acceptable to handle XML documents or E-Mails
+                in memory as a string and always completely retrieve or store them in one chunk this will
+                hardly be a good idea for video files for example.
+            </p>
 
+            <p>
+                This HOWTO will explain:
+            </p>
+            <ol>
+                <li><a href="#whyLobs">Why you would want to store large objects in the database</a></li>
+                <li><a href="#discussLargeObjects">"LARGE" versus LOB data types (considering as oracle example)</a></li>
+                <li><a href="#lobsWithOjb">LOB handling in OJB using JDBC LOB types</a></li>
+            </ol>
+            <p>
+                This tutorial presumes you are familiar with the basics of OJB.
+            </p>
+        </section>
+
+        <anchor id="lobsWithOjb"/>
         <section>
-            <title>Using Oracle LOB Data Types with OJB</title>
+            <title>Large Objects in OJB</title>
+            <p>
+                In the following sections you will learn how OJB handle LOB's and how to avoid
+                pitfalls caused by the different "implementation quality" of JDBC driver.
+            </p>
+            <p>
+                In OJB's <a href="site:test-suite">test-suite</a> you can find a tests handling LOB values. The test
+                case is called <code>org.apache.ojb.broker.lob.LOBTest</code>.
+            </p>
+            <p>
+                To handle LOB content with OJB you have two possibilities:
+            </p>
+            <ul>
+                <li>
+                    use the database specific method and classes. OJB provide methods to access
+                    the current used <a href="site:connection/obtain-connection">database connection</a>.
+                </li>
+                <li>
+                    use a specific helper class provided by OJB to deal with LOB content. This is described
+                    in detailed below.
+                </li>
+            </ul>
+
+
+            <anchor id="locatorObjects"/>
             <section>
-                <title>Introduction</title>
+                <title>JDBC Locator objects</title>
                 <p>
-                    In a lot of applications there is a need to store large text or binary objects into the database.
-                    The definition of large usually means that the object's size is beyond the maximum length of
-                    a character field. In Oracle this means the objects to be stored can grow to &gt; 4 KB each. </p>
+                    Since JDK 1.2/JDBC 2.0 it is possible to manage <em>binary large objects</em> and
+                    <em>character large objects</em> via <code>java.sql.Blob</code> and
+                    <code>java.sql.Clob</code>. To avoid loading/materialisation of LOB columns
+                    for each query result set <em>Locator</em> objects are recommended by the specification
+                    (JDBC 3.0 specification section 16):
+                </p>
+                <p>
+                    "<em>Locators - new entities that are logical pointers to data that resides on the
+                    database server. A LOCATOR exists in the client environment and is a transient,
+                    logical pointer to data on the server. A locator typically refers to data that is too
+                    large to materialize on the client, such as images or audio. There are operators
+                    defined at the SQL level to retrieve random-access pieces of the data denoted by
+                    the locator.</em>"
+                </p>
+                <p>
+                    Currently not all database JDBC driver implement <code>java.sql.Blob</code> and
+                    <code>java.sql.Clob</code> in this way - <a href="#driverAndLocatorObjects">more detailed here</a>.
+                </p>
+            </section>
+
+            <anchor id="driverAndLocatorObjects"/>
+            <section>
+                <title>JDBC driver and <em>Locator Objects</em></title>
+                <p>
+                    Many database JDBC driver support <code>java.sql.Blob</code> and
+                    <code>java.sql.Clob</code> objects. But not all implement the "locator pattern",
+                    some still materialize the whole LOB object when Blob/Clob is returned to
+                    the client. They behave like "normal" fields and not as a logical pointer to the
+                    real data - If you deal with really large objects this will have an huge
+                    <a href="#discussLargeObjects">performance impact</a> and can kill your application.
+                </p>
+                <p>
+                    Thus it's important to check whether or not the used JDBC driver supports
+                    the <a href="#locatorObjects">"locator pattern"</a> recommended by the JDBC
+                    specification.
+                </p>
+            </section>
+
+            <anchor id="lobMapping"/>
+            <section>
+                <title>LOB mapping</title>
+                <p>
+                    The mapping of <em>BLOB</em> and <em>CLOB</em> columns in OJB is similar to "normal"
+                    database columns. OJB need to know the java-object field name, the database column name and
+                    the jdbc type.
+                </p>
+                <p>
+                    Assume we have a persistence capable object called <code>LobObject</code> with LOB fields:
+                </p>
+                <source><![CDATA[
+public class LobObject implements Serializable
+{
+    private int id;
+    private Blob blob;
+    private Clob clob;
+
+    public LobObject() {}
+
+    public int getId() {return id;}
+    public void setId(int id) {this.id = id;}
+    public Blob getBlob() {return blob;}
+    public void setBlob(Blob blob) {this.blob = blob;}
+    public Clob getClob() {return clob;}
+    public void setClob(Clob clob) {this.clob = clob;}
+}
+                ]]></source>
+                <p>
+                    Then the mapping would look like this:
+                </p>
+                <source><![CDATA[
+<class-descriptor
+  class="my.LobObject"
+  table="BLOB_TEST"
+>
+  <field-descriptor
+     name="id"
+     column="ID"
+     jdbc-type="INTEGER"
+     primarykey="true"
+     autoincrement="true"
+  />
+  <field-descriptor
+     name="blob"
+     column="BLOB_VALUE_"
+     jdbc-type="BLOB"
+  />
+  <field-descriptor
+     name="clob"
+     column="CLOB_VALUE_"
+     jdbc-type="CLOB"
+  />
+</class-descriptor>
+                ]]></source>
+                <p>
+                    More information about how to map columns in OJB see
+                    <a href="site:repository">repository section</a>.
+                    <br/>
+                    In your persistence capable object OJB expects type <code>java.sql.Blob</code>
+                    for field <em>blob</em> and <code>java.sql.Clob</code> for field <em>clob</em>.
+                </p>
+                <note>
+                    If a jdbc <em>BLOB</em> column is mapped to a java-object <em>byte[]</em> field, OJB
+                    does internally materialize the Blob object to byte array.
+                    <br/>
+                    If a jdbc <em>CLOB</em> column is mapped to a java-object <em>String</em> field, OJB
+                    does internally materialize the Clob object to a String value.
+                </note>
+            </section>
+
 
+            <anchor id="insertLobs"/>
+            <section>
+                <title>Insert LOB's</title>
                 <p>
-                    Depending on the application you are developing your "large objects" may either be in the range of some Kilobytes
-                    (for example when storing text-only E-Mails or regular XML documents), but they may also extend to several Megabytes
-                    (thinking of any binary data such as larger graphics, PDFs, videos, etc.). </p>
+                    There is no difference in insert of persistence capable objects with LOB-fields
+                    compared to objects without - beside populate the LOB-fields.
+                    <br/>
+                    OJB provide a specific helper class to create new LOB content -
+                    <a href="ext:lob-helper"><code>org.apache.broker.lob.LobHelper</code></a>.
+                    This class provides methods to obtain <em>new</em> <code>java.sql.Blob</code>
+                    and <code>java.sql.Clob</code> instances.
+                </p>
+                <source><![CDATA[
+public Blob newBlob(InputStream in);
+public Blob newBlob(byte[] value);
+public Blob newBlob();
+public Clob newClob(Reader reader);
+public Clob newClob(String value);
+public Clob newClob();
+                ]]></source>
+                <p>
+                    To access this class use the service method in <code>PersistenceBroker</code> class:
+                </p>
+                <source><![CDATA[
+LobHelper lh = broker.serviceLobHelper();
+                ]]></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.
+                </p>
+                <source><![CDATA[
+// get byte stream of the image
+InputStream in = new FileInputStream(...get Image);
+// mandatory to start a tx
+broker.beginTransaction();
+// obtain Blob
+Blob b = broker.serviceLobHelper().newBlob(in);
+LobObject obj = new LobObject();
+obj.setBlob(b);
+broker.store(obj);
+broker.commitTransaction();
+                ]]></source>
+                <p>
+                    The <code>InputStream</code> <em>in</em> will normally be closed by the jdbc-driver.
+                </p>
+                <note>
+                    Not all databases will support creation of LOB content described above. It could happen
+                    that you e.g. first have to insert a row in table <em>BLOB_TEST</em> with an database specific
+                    <em>empty LOB-locator</em> (e.g. with an embedded function call in the insert statement)
+                    or something similar.
+                </note>
+
+
+                <anchor id="insertLobsDatabaseSpecific"/>
+                <section>
+                    <title>Insert LOB content via database specifc methods - considering as Oracle example</title>
+                    <p>
+                        Sometime it's necessary to use database specific methods to create LOB content. The
+                        example below show how this can be handled considering as Oracle example based on the
+                        <a href="#lobMapping">example mapping above</a>.
+                    </p>
+                    <source><![CDATA[
+// get byte stream of the image
+InputStream instream = new FileInputStream(...get Image);
+
+// mandatory to start a tx
+broker.beginTransaction();
+// create new object
+LOBTest.LobObject obj = new LobObject();
+// insert new object to get a valid PK
+broker.store(obj);
+// get the current Connection
+Connection con = broker.serviceConnectionManager().getConnection();
+Statement stmt = con.createStatement();
+// use database specific function to create an empty LOB
+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);
+
+Blob blob = obj.getBlob();
+OutputStream outstream = blob.setBinaryStream(1);
+byte[] buffer = new byte[100];
+int length = -1;
+while ((length = instream.read(buffer)) != -1)
+outstream.write(buffer, 0, length);
+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);
+broker.commitTransaction();
+                    ]]></source>
+                    <p>
+                        More detailed information about
+                        <a href="site:connection/obtain-connection">
+                            how to access <code>java.sql.Connection</code> instances here</a>.
+                    </p>
+                    <p>
+                        It's also possible to use <a href="site:query/report-queries">Report Queries</a> to directly
+                        query LOB content.
+                    </p>
+                </section>
 
+            </section>
+
+
+            <anchor id="queryLobs"/>
+            <section>
+                <title>Querying LOB content</title>
                 <p>
-                    In practice, the interface between your application and the database used for fetching and storing of your "large objects"
-                    needs to be different depending on the expected size. While it is probably perfectly acceptable to handle XML documents or E-Mails
-                    in memory as a string and always completely retrieve or store them in one chunk this will hardly be a good idea for video files for example.</p>
+                    There is no difference in query persistence capable objects with LOB-fields
+                    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>
-                    This HOWTO will explain:
+                    
+                </p>
+            </section>
+
+
+            <anchor id="refreshLobs"/>
+            <section>
+                <title>Refresh LOB's</title>
+                <p>
+                    ########## to be written #########
                 </p>
-                <ol>
-                    <li>Why you would want to store large objects in the database</li>
-                    <li>Oracle LARGE versus LOB data types</li>
-                    <li>LOB handling in OJB using JDBC LOB types</li>
-                </ol>
 
+                <anchor id="autoRefresh"/>
+                <section>
+                    <title>Enable automatic refresh of LOB content</title>
+                    <p>
 
+                    </p>
+                </section>
+
+            </section>
+
+
+            <anchor id="updateLobs"/>
+            <section>
+                <title>Update LOB's</title>
                 <p>
-                    This tutorial presumes you are familiar with the basics of OJB.
+                    ########## to be written #########
                 </p>
             </section>
+
         </section>
 
-        <section>
-            <title>Backgrounder: Large objects in databases</title>
 
+
+        <anchor id="background"/>
+        <section>
+            <title>Background: Large objects in databases</title>
             <p>
                 This section is meant to fill in non-DBA people on some of the topics you need to understand
                 when discussing large objects in databases.
             </p>
 
+            <anchor id="whyLobs"/>
             <section>
                 <title>Your database: The most expensive file system?</title>
-
                 <p>
-                    Depending on background some people tend to store anything in a database while others are biased against that. As databases use a file system
-                    for physical storage anyway, why would it make sense to store pictures, videos and the like as a large object in a database rather that just
-                    create a set of folders and store them right into the database.
+                    Depending on background some people tend to store anything in a database while others are
+                    biased against that. As databases use a file system for physical storage anyway, why
+                    would it make sense to store pictures, videos and the like as a large object in a database
+                    rather that just create a set of folders and store them right into the database.
                 </p>
 
                 <p>
-                    When listening to Oracle's marketing campaingns one might get the impression that there is no need to have plain filesystems anymore and that
-                    they all will vanish and be replaced by Oracle database servers. If that happened this would definitely boast Oracle's revenues, but at the same
-                    time make IT cost in companies explode.
+                    When listening to Oracle's marketing campaingns one might get the impression that there is
+                    no need to have plain filesystems anymore and that they all will vanish and be replaced
+                    by Oracle database servers. If that happened this would definitely boast Oracle's revenues,
+                    but at the same time make IT cost in companies explode.
                 </p>
-
                 <p>
-                    But there are applications where it in fact makes sense to have the database take care of unstructured data that you would otherwise just store in a file.
-                    The most common criteria for storing non-relational data in the database instead of storing it directly into the file system is whenever there is a strong
+                    But there are applications where it in fact makes sense to have the database take care of
+                    unstructured data that you would otherwise just store in a file.
+                    The most common criteria for storing non-relational data in the database instead of
+                    storing it directly into the file system is whenever there is a strong
                     link between this non-relatinal and some relational data.
                 </p>
-
                 <p>
                     Typical examples for that would be:
                 </p>
@@ -98,135 +405,130 @@
                     <li>Pictures or videos of houses in a real estate agent's offer database</li>
                     <li>E-Mails related to a customer's order</li>
                 </ol>
-
-
                 <p>
-                    If you are not storing these objects into the database you would need to create a link between the relational and the non-relational data by saving
-                    filenames in the database. This means that you application is responsible for managing this weak link in any respect. In order to make sure your
+                    If you are not storing these objects into the database you would need to create a link
+                    between the relational and the non-relational data by saving
+                    filenames in the database. This means that you application is responsible for managing
+                    this weak link in any respect. In order to make sure your
                     application will be robust you need to make sure in your own code that
                 </p>
                 <ol>
-                    <li>When creating a new record you create a valid and unique filename for storing the object.</li>
-                    <li>When deleting a record you delete the corresponding file as well</li>
-                    <li>When accessing the file referred to in the record you double-check the file is there and no locked</li>
+                    <li>when creating a new record you create a valid and unique filename for storing the object.</li>
+                    <li>when deleting a record you delete the corresponding file as well</li>
+                    <li>when accessing the file referred to in the record you double-check the file is
+                        there and no locked</li>
                 </ol>
                 <p>
                     (There might be other, more subtle implications.)
                 </p>
 
                 <p>
-                    All this is done for you by the database in case you choose to store your objects there. In addition to that, when discussing text data, a database might
-                    come with an option to automatically index the stored text documents for easy retrievel. This would allow you to perform an SQL seach such as "give me all
-                    customers that ever referred to the project foo in an e-mail". (In Oracle you need to install the InterMedia option, aka Oracle Text in order to get this
-                    extra functionality. Several vendors have also worked on technologies that allowed to seach rich content such as PDFs files, pictures or even sound or
-                    video stored in a database from SQL.)
+                    All this is done for you by the database in case you choose to store your objects there.
+                    In addition to that, when discussing text data, a database might
+                    come with an option to automatically index the stored text documents for easy retrievel.
+                    This would allow you to perform an SQL seach such as "give me all
+                    customers that ever referred to the project foo in an e-mail".
+                    (In Oracle you need to install the <em>InterMedia</em> option, aka <em>Oracle Text</em>
+                    in order to get this extra functionality. Several vendors have also worked on
+                    technologies that allowed to seach rich content such as PDFs files, pictures or
+                    even sound or video stored in a database from SQL.)
                 </p>
             </section>
 
 
+            <anchor id="discussLargeObjects"/>
             <section>
-                <title>Oracle LARGE versus LOB datatypes</title>
-
-                <p>Some people are worried about the efficiency of storing large objects in databases and the implications on performance. They are not necessarily entirely
-                    wrong in fearing that storing large objects in databases might be problematic the best or might require a lot of tweaks to parameters in order to be able
-                    to handle the large objects. It all depends on how a database implements storing large objects.</p>
+                <title>"LONG" versus LOB datatypes (considering as oracle example)</title>
+                <p>
+                    Some people are worried about the efficiency of storing large objects in databases and the
+                    implications on performance. They are not necessarily entirely wrong in fearing that storing
+                    large objects in databases might be problematic the best or might require a lot of tweaks
+                    to parameters in order to be able to handle the large objects.
+                    It all depends on how a database implements storing large objects.
+                </p>
 
                 <p>
-                    Oracle comes with two completely different mechanisms for that:
+                    For example <em>Oracle</em> comes with two completely different mechanisms for that:
                 </p>
                 <ol>
-                    <li>LARGE objects</li>
-                    <li>LOB objects</li>
+                    <li>"LONG" objects (like LONG, LONG RAW, LONGVARCHAR, ...)</li>
+                    <li>LOB objects (like BLOB, CLOB, NCLOB, BFILE)</li>
                 </ol>
                 <p>
-                    When comparing the LARGE datatypes such as (*fixme*) to the LOB datatypes such as CLOB, BLOB, NCLOB (*fixme*) they don't read that different at first.
+                    When comparing the <em>LONG</em> datatypes to the <em>LOB</em> datatypes they don't
+                    read that different at first.
                     But there is a huge difference in how they are handled both internally inside the
                     database as well when storing and retrieving from the database client.
                 </p>
 
                 <p>
-                    LARGE fields are embedded directly into the table row. This has some consequences you should be aware of:
+                    <em>LONG columns</em> are embedded directly into the table row. This has some consequences
+                    you should be aware of:
                 </p>
                 <ol>
                     <li>
-                        If your record is made up of 5 VARCHAR fields with a maximum length of 40 bytes each and one LONGVARCHAR and you store 10 MB into the LONGVARCHAR column,
+                        If your record is made up of 5 VARCHAR fields with a maximum length of 40 bytes each
+                        and one LONGVARCHAR and you store 10 MB into the LONGVARCHAR column,
                         your database row will extent to 10.000.200 bytes or roughly 10 MB.
                     </li>
                     <li>
-                        The database always reads or writes the entire row. So if you do a SELECT on the VARCHAR fields in order to display their content in a user interface as
-                        a basis for the user to decide if he or she will need the content of the LONGVARCHAR at all the database will already have fetched all the 10 MB. If you SELECT
+                        The database always reads or writes the entire row. So if you do a SELECT on the
+                        VARCHAR fields in order to display their content in a user interface as
+                        a basis for the user to decide if he or she will need the content of the
+                        LONGVARCHAR at all the database will already have fetched all the 10 MB. If you SELECT
                         and display 25 records each with a 10 MB object in it this will mean about 250 MB of I/O.
                     </li>
                     <li>
-                        When storing or fetching such a row you need to make sure your fetch buffer is sized appropriately.
+                        When storing or fetching such a row you need to make sure your fetch buffer is sized
+                        appropriately.
                     </li>
                 </ol>
-                <p>In practice this cannot be efficient. It might work as long as you stay in the KB range, but you will most likely run into trouble as soon as it gets into the MBs
-                    per record. Additionally, there are more limitations to the concept of LONG datatypes such as limiting the number of them you can have in one row and how you can
+                <p>
+                    In practice this cannot be efficient. It might work as long as you stay in the KB range,
+                    but you will most likely run into trouble as soon as it gets into the MBs
+                    per record. Additionally, there are more limitations to the concept of LONG datatypes
+                    such as limiting the number of them you can have in one row and how you can
                     index them. This is probably why Oracle decided to deprecate LONG datatypes in favor
                     of LOB columns.
                 </p>
 
                 <p>
-                    A lot of non-Oracle-DBA people believe that LOB means "large OBject" because some other vendors have used the term BLOB for "Binary Large OBject" in their products.
+                    A lot of non-Oracle-DBA people believe that <em>LOB</em> means <em>Large OBject</em>
+                    because some other vendors have used the term BLOB for "Binary Large OBject"
+                    in their products.
                     This is not only wrong but - even worse - misleading, because people are asking:
                     "What's the difference between large and long?" (Bear with all non native English
                     speakers here, please!)
                 </p>
 
                 <p>
-                    Instead, LOB stands for Locator OBject which exactly describes what is is. It is a pointer to the place where the actual data itself is stored. This locator
-                    will need only occupy some bytes in the row thus not harming row size at all. So all the issues discussed above vanish immediatelly. For the sake of simplicity
-                    think of a LOB as a pointer to a file on the databases internal file system that stores the actual content of that field. (Oracle might use plain files or
+                    Instead, <em>LOB</em> stands for <em>Locator OBject</em> which exactly describes what is is.
+                    It is a pointer to the place where the actual data itself is stored. This locator
+                    will need only occupy some bytes in the row thus not harming row size at all. So all the
+                    issues discussed above vanish immediatelly. For the sake of simplicity
+                    think of a <em>LOB</em> as a pointer to a file on the databases internal file system that
+                    stores the actual content of that field. (Oracle might use plain files or
                     different mechanisms in their implementation, we don't have to care.)
                 </p>
 
                 <p>
-                    But as there is always a trade-off while LOBs are exstremely handy inside a row, they are more complex to store and retrieve. As opposed to all other column types
-                    their actual content stays where it is even if you transfer the row from the database to the client. All that goes over the wire in that case will be a token
+                    But as there is always a trade-off while LOBs are exstremely handy inside a row, they are
+                    more complex to store and retrieve. As opposed to all other column types
+                    their actual content stays where it is even if you transfer the row from the
+                    database to the client. All that goes over the wire in that case will be a token
                     representing the actual LOB column content.
                 </p>
 
-                <p>In order to read the content or to write LOB content it needs to open a separate stream connection over the network that can be read from or written to similar
-                    to a file on a network file system. JDBC (starting at version *fixme*) comes with special objects such as java.sql.Blob and java.sql.Clob to access the content of
-                    LOBs that do not represent character arrays or strings but streams!
-                </p>
-            </section>
-        </section>
-
-
-        <section>
-            <title>Large Objects in OJB</title>
-
-            <p>After having skipped the above Backgrounder (in case you do Oracle administration for a living)
-                of having read and understood it (hopefully applies to the
-                rest of us) now that you've most likely decided to go for LOBs and forget about LONGs how
-                is this handled with OJB?
-            </p>
-
-            <section>
-                <title>Strategy 1: Using streams for LOB I/O</title>
-                <p>
-                    ########## to be written #########
-                </p>
-
-            </section>
-
-            <section>
-                <title>Strategy 2: Embedding OJB content in Java objects</title>
                 <p>
-                    ########## to be written #########
-                </p>
-            </section>
-
-            <section>
-                <title>Querying CLOB content</title>
-
-                <p>
-                    ########## to be written #########
+                    In order to read the content or to write LOB content it needs to open a separate stream
+                    connection over the network that can be read from or written to similar
+                    to a file on a network file system. JDBC (starting at JDK 1.2) comes with
+                    special objects such as <code>java.sql.Blob</code> and <code>java.sql.Clob</code> to access
+                    the content of LOB's that do not represent character arrays or strings but streams!
                 </p>
             </section>
         </section>
+
     </body>
 </document>
 

Modified: db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/howtos/summary.xml
URL: http://svn.apache.org/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/howtos/summary.xml?rev=398754&r1=398753&r2=398754&view=diff
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/howtos/summary.xml (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/docu/howtos/summary.xml Mon May  1 17:30:24 2006
@@ -50,7 +50,7 @@
                 <a href="site:howto/stored-procedures">Using OJB with stored procedures</a>
             </li>
             <li>
-                <a href="site:howto/use-lobs">Using Oracle LOB's</a>
+                <a href="site:howto/use-lobs">Work with LOB Data Types</a>
             </li>
             <li>
                 <a href="site:howto/use-spring">Using Spring with OJB</a>

Modified: db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/site.xml
URL: http://svn.apache.org/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/site.xml?rev=398754&r1=398753&r2=398754&view=diff
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/site.xml (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/doc/forrest/src/documentation/content/xdocs/site.xml Mon May  1 17:30:24 2006
@@ -112,6 +112,7 @@
                 <lookup-pb href="#lookup-pb"/>
                 <multiple-databases href="#multiple-databases"/>
                 <listener href="#listener"/>
+                <detect-leak href="#detect-leak"/>
             </pb-guide>
             <odmg-guide label="ODMG API guide" href="odmg-guide.html">
                 <no-oql href="#no-oql"/>
@@ -185,6 +186,7 @@
                 <odmg-oql href="#odmg-oql"/>
                 <jdo-oql href="#jdo-oql"/>
                 <prefetched-relationships href="#prefetched-relationships"/>
+                <report-queries href="#report-queries"/>
             </query>
             <metadata label="Metadata handling" href="metadata.html">
                 <without-repository href="#without-repository"/>
@@ -223,7 +225,7 @@
             <large-metadata label="Build large Metadata Mappings" href="howto-build-mappings.html"/>
             <anonymous-keys label="Anonymous Keys" href="howto-use-anonymous-keys.html"/>
             <db-sequences label="Using database sequences" href="howto-use-db-sequences.html"/>
-            <use-lobs label="Use Oracle LOB's" href="howto-use-lobs.html"/>
+            <use-lobs label="Using LOB Types" href="howto-use-lobs.html"/>
             <clustering label="Work in clustered environment" href="howto-work-with-clustering.html"/>
             <stored-procedures label="Work with Stored Procedures" href="howto-work-with-stored-procedures.html"/>
             <use-spring label="Using Spring with OJB" href="howto-use-spring.html"/>
@@ -267,6 +269,7 @@
             <pb-state-listener href="org/apache/ojb/broker/PBStateListener.html"/>
             <pb-aware href="org/apache/ojb/broker/PersistenceBrokerAware.html"/>
             <query-factory href="org/apache/ojb/broker/query/QueryFactory.html"/>
+            <lob-helper href="org/apache/ojb/broker/lob/LobHelper.html"/>
 
             <!-- odmg-api classes -->
             <odmg-transaction href="org/odmg/Transaction.html"/>



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