Sophie

Sophie

distrib > Fedora > 13 > i386 > by-pkgid > fffbd1c50e8102746e8aec13b7d53ba8 > files > 36

castor-doc-0.9.5-5.fc12.1.i686.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head><title>Castor JDO FAQ</title><link rel="stylesheet" href="default.css"></head><body bgcolor="#ffffff" link="#6763a9" vlink="#6763a9" topmargin="0" bottommargin="0" leftmargin="0" marginheight="0" marginwidth="0"><a name="top"></a><table border="0" cellpadding="0" cellspacing="0" height="400"><tr><td width="10" valign="top" align="left" bgcolor="#7270c2"><img src="images/dotTrans.gif" width="1" height="1" border="0"></td><td width="115" valign="top" align="left" bgcolor="#7270c2"><img src="images/dotTrans.gif" width="1" height="1" border="0"></td><td width="7" valign="top" align="left"><img src="images/dotTrans.gif" border="0" width="1" height="1"></td><td width="70" valign="top" align="left"><img src="images/dotTrans.gif" width="70" height="6" border="0"></td><td width="400" valign="top" align="left"><img src="images/top_2.gif" width="400" height="6" border="0"></td><td width="120" valign="top" align="left"><img src="images/line_purple.gif" width="120" height="6" border="0"></td></tr><tr><td width="10" bgcolor="#7270c2" valign="top" align="left"><img src="images/dotTrans.gif" border="0" width="1" height="1"></td><td width="115" bgcolor="#7270c2" valign="top" align="left"><img src="images/dotTrans.gif" border="0" width="1" height="1"></td><td width="7" bgcolor="#ffffff" valign="top" align="left"></td><td width="70" valign="top" align="left"><img src="images/dotTrans.gif" width="1" height="1" border="0"></td><td width="400" valign="middle" align="left"><a href="http://www.exolab.org"><span class="menuTopOff">ExoLab</span></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://openejb.sf.net"><span class="menuTopOff">OpenEJB</span></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://openjms.sf.net"><span class="menuTopOff">OpenJMS</span></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://openorb.sf.net"><span class="menuTopOff">OpenORB</span></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://castor.exolab.org"><span class="menuTopOn">Castor</span></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://tyrex.sf.net"><span class="menuTopOff">Tyrex</span></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="images/dotTrans.gif" width="1" height="2" border="0"></td><td width="120" height="20" valign="top" align="left">&nbsp;</td></tr><tr><td width="10" bgcolor="#7270c2" valign="top" align="left"><img src="images/dotTrans.gif" width="10" height="3" border="0"></td><td width="115" bgcolor="#7270c2" valign="top" align="right"><img src="images/line_sm.gif" width="105" height="3" border="0"></td><td width="7" bgcolor="#a9a5de" valign="top" align="left"><img src="images/line_sm.gif" width="7" height="3" border="0"></td><td width="70" valign="top" align="left"><img src="images/line_light.gif" width="70" height="3" border="0"></td><td width="400" valign="top" align="left"><img src="images/line_light.gif" width="400" height="3" border="0"></td><td width="120" valign="top" align="left"><img src="images/dotTrans.gif" border="0" width="1" height="1"></td></tr><tr><td bgcolor="#7270c2" valign="top" align="left"><img src="images/dotTrans.gif" width="10" height="10" border="0"></td><td width="115" bgcolor="#7270c2" valign="top" align="left"><img src="images/dotTrans.gif" width="1" height="2" border="0"><br><table border="0" cellpadding="0" cellspacing="0"><tr><td valign="top" align="left"><span class="subMenuOn">Main</span></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="index.html"><span class="subMenuOff">Home</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="download.html"><span class="subMenuOff">Download</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="api/overview-summary.html"><span class="subMenuOff">API</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="schema.html"><span class="subMenuOff">Schema</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="lists.html"><span class="subMenuOff">Mailing Lists</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="cvs.html"><span class="subMenuOff">CVS / Bugzilla</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="support.html"><span class="subMenuOff">Support</span></a></td></tr></table><br><table border="0" cellpadding="0" cellspacing="0"><tr><td valign="top" align="left"><span class="subMenuOn">XML</span></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="xml-framework.html"><span class="subMenuOff">Using XML</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="sourcegen.html"><span class="subMenuOff">Source Generator</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="xmlschema.html"><span class="subMenuOff">Schema Support</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="xml-mapping.html"><span class="subMenuOff">XML Mapping</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="xml-faq.html"><span class="subMenuOff">XML FAQ</span></a></td></tr></table><br><table border="0" cellpadding="0" cellspacing="0"><tr><td valign="top" align="left"><span class="subMenuOn">JDO</span></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="jdo.html"><span class="subMenuOff">Using JDO</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="database-conf.html"><span class="subMenuOff">JDO Config</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="types.html"><span class="subMenuOff">Types</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="jdo-mapping.html"><span class="subMenuOff">JDO Mapping</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="jdo-faq.html"><span class="subMenuOff">JDO FAQ</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="castor-one.html"><span class="subMenuOff">Other Features</span></a></td></tr></table><br><table border="0" cellpadding="0" cellspacing="0"><tr><td valign="top" align="left"><span class="subMenuOn">Advanced JDO</span></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="oql.html"><span class="subMenuOff">OQL</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="locking.html"><span class="subMenuOff">Trans. &amp; Locks</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="design-persist.html"><span class="subMenuOff">Design</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="key-generator.html"><span class="subMenuOff">KeyGen</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="long-transact.html"><span class="subMenuOff">Long Trans.</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="nested-attr.html"><span class="subMenuOff">Nested Attrs.</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="pooling.html"><span class="subMenuOff">Pooling Examples</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="postgresql-blobs.html"><span class="subMenuOff">Blobs and PostgreSQL</span></a></td></tr></table><br><table border="0" cellpadding="0" cellspacing="0"><tr><td valign="top" align="left"><span class="subMenuOn">More</span></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="presentations.html"><span class="subMenuOff">Presentations</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="examples.html"><span class="subMenuOff">The Examples</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="extras.html"><span class="subMenuOff">Extras and 3rd Party Tools</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="test-framework.html"><span class="subMenuOff">Test Framework -- JDO</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="ctf.html"><span class="subMenuOff">Test Framework -- XML</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="conf-lib.html"><span class="subMenuOff">Configuration</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="tips-tricks.html"><span class="subMenuOff">Tips &amp; Tricks</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="javadoc/overview-summary.html"><span class="subMenuOff">Full JavaDoc</span></a></td></tr></table><br><table border="0" cellpadding="0" cellspacing="0"><tr><td valign="top" align="left"><span class="subMenuOn">About</span></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="license.html"><span class="subMenuOff">License</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="contributors.html"><span class="subMenuOff">Contributors</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="status.html"><span class="subMenuOff">Status, Todo</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="changelog.html"><span class="subMenuOff">Changelog</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="library.html"><span class="subMenuOff">Library</span></a></td></tr><tr><td valign="top" align="left">&nbsp;&nbsp;<a href="contacts.html"><span class="subMenuOff">Contact</span></a></td></tr></table><br></td><td width="7" bgcolor="#a9a5de" valign="top" align="left">&nbsp;</td><td width="70" valign="top" align="left">&nbsp;</td><td rowspan="4" width="400" valign="top"><table cols="2" rows="2" border="0" cellpadding="0" cellspacing="0" width="400"><tr><td valign="top" align="left"><br><img border="0" height="34" hspace="0" src="images/castor.gif" vspace="0" width="115"><br><img border="0" height="10" hspace="0" src="images/dotTrans.gif"></td><td width="120" height="5" valign="top" align="right"><a href="http://www.exolab.org"><img src="images/logo_exolab.gif" hspace="0" vspace="10" width="77" height="20" border="0"></a></td></tr></table><p></p><p></p><br><span class="bodyGrey"><a href="#Castor's-relation-to-other-specifications">Castor's relation to other specifications</a><br></span><span class="bodyGrey"><a href="#XML-related-questions">XML related questions</a><br></span><span class="bodyGrey"><a href="#Technical-questions">Technical questions</a><br></span><span class="bodyGrey"><a href="#OQL">OQL</a><br></span><span class="bodyGrey"><a href="#Features-requests">Features requests</a><br></span><span class="bodyGrey"><a href="#Data-model-issues">Data model issues</a><br></span><span class="bodyGrey"><a href="#Castor-JDO-design">Castor JDO design</a><br></span><span class="bodyGrey"><a href="#Working-with-open-source-databases">Working with open source databases</a><br></span><span class="bodyGrey"><a href="#Integrating-Castor's-logging-with-Log4J">Integrating Castor's logging with Log4J</a><br></span><span class="bodyGrey"><a href="#Lazy-Loading-related-questions">Lazy Loading related questions</a><br></span><span class="bodyGrey"><a href="#Tuning-for-LOBs">Tuning for LOBs</a><br></span><br><a name="Castor's-relation-to-other-specifications"><h2>Castor's relation to other specifications</h2></a>         <p><span class="bodyGrey"><b>Does Castor JDO comply with the SUN JSR-000012 specification?</b></span></p>          <p><span class="bodyGrey">No, Castor JDO doesn't comply with the SUN's JDO specification.</span></p>          <p><span class="bodyGrey">Although Castor JDO carries very similar goals as SUN's JDO, it has been developed independently from the JSR.</span></p>          <p><span class="bodyGrey">Although it is not impossible to shape (perhaps &quot;hammer&quot; is a more descriptive verb) Castor JDO into the SUN's JDO specification, there are several major technical differences which make it unfavorable to do so. Castor is RDBMS centric. Each persistence object loaded by Castor is locked. Locks in Castor are observable, meaning that locks may not be granted because of timeout or deadlock. On the other hand, the SUN's JDO hides details about locks.</span></p>          <p><span class="bodyGrey">Internally, Castor JDO maintains a single copy of lock (and cache) for each active persistence object for all transaction. SUN's JDO specification implicitly requires a copy of cache per object per transaction. SUN's JDO also implicitly require a bytecode modifier which Castor doesn't require. </span></p>          <p><span class="bodyGrey">Castor also provides other features, such as key generators, long transaction support and OQL query which cannot be found in SUN's JSR. </span></p>           <p><span class="bodyGrey"><b>Is Castor JDO better than EJB CMP?</b></span></p>          <p><span class="bodyGrey">The relation between JDO and EJB Bean is sometimes more complicated than simply saying, &quot;one is better than the other&quot;.</span></p>          <p><span class="bodyGrey">An Entity Bean may manage to persist itself. (the EJB specification calls this Bean Managed Persistence, or bmp) It may also rely on its EJB container to do so. (EJB calls this Container Managed Persistence, or cmp). </span></p>          <p><span class="bodyGrey">For bmp, an Entity Bean may use Castor JDO as its persistence mechanism, or use another method, such as dealing with JDBC directly, as its persistence mechanism. </span></p>          <p><span class="bodyGrey">For cmp, an EJB Container vendor may implement their cmp on top of Castor JDO. In such an implementation, Castor JDO will be used to persist the Entity Bean.</span></p>          <p><span class="bodyGrey">If a developer would like to take advantage of EJB's life-cycle management, security, the &quot;write once deploy anywhere&quot; promise and other distributed business application facilities, then EJB will be the right choice.</span></p>          <p><span class="bodyGrey">Otherwise, the fact that Castor is simple, is open source (you can always include Castor in your application or product), has much less overhead, provides more design freedom, and is integrated with Castor XML may be enough of a reason to choose Castor JDO.</span></p>     <a name="XML-related-questions"><h2>XML related questions</h2></a>         <p><span class="bodyGrey"><b>Is it possible to make xml marshalling transactionally using Castor?</b></span></p>          <p><span class="bodyGrey">No. The decision of putting XML and JDO together is NOT intended to make XML marshalling transactional.</span></p>          <p><span class="bodyGrey">Instead, the integration is done to help developers of a typical client-server situation: an application server receives incoming XML messages, process the messages and replies to the client. </span></p>          <p><span class="bodyGrey">With Castor, incoming XML messages can be unmarshaled into data objects. Required information can be obtained from a database using JDO in form of data objects. With this approach, all data manipulation can be done in an object-oriented way. Changes to JDO data objects can be committed transactionally, and result data objects can be marshaled into XML and returned to the client. </span></p>          <p><span class="bodyGrey"><b>Is it possible to do queries on a XML file using Castor?</b></span></p>          <p><span class="bodyGrey">No, Castor does not provide an OQL query facility on a XML file. If querying is important for you, you should consider using a DBMS to store your data instead of using XML files, especially if querying performance is a concern.</span></p>      <a name="Technical-questions"><h2>Technical questions</h2></a>         <p><span class="bodyGrey"><b>Where can I find some examples to start with?</b></span></p>          <p><span class="bodyGrey">Download the full CVS snapshot and look into the castor\src\tests\jdo directory</span></p>            <p><span class="bodyGrey"><b>I have encountered problems using Sun JDBC-ODBC bridge with Castor...</b></span></p>          <p><span class="bodyGrey">It cannot be used with Castor, because it doesn't allow to keep two open ResultSets at the same time.            Either use JDBC driver of type &gt; 1, or use some other JDBC-ODBC bridge without such restriction            (for example, from <a href="http://www.easysoft.com">Easysoft</a>).</span></p>            <p><span class="bodyGrey"><b>My get-method for the Collection of dependent objects returns <tt>null</tt>. Why?</b></span></p>          <p><span class="bodyGrey">You should initialize the Collection yourself:          <span class="bodyBlack"><pre>
  private Collection _children = new ArrayList();

  public Collection getChildren() {
      return _children;
  }
         </pre></span>         </span></p>            <p><span class="bodyGrey"><b>Should my JDO classes implement some special interface?</b></span></p>          <p><span class="bodyGrey">In general, no. If you need some behavior that is not directly supported by Castor, you can implement interface org.exolab.castor.jdo.Persistent.         In order to use dirty checking for long transaction you should implement interface org.exolab.castor.jdo.TimeStampable.         If you need an example of use of these interfaces, see Persistent.java and TestPersistent.java among Castor JDO tests.</span></p>            <p><span class="bodyGrey"><b>Can Castor automatically create/remove related objects?</b></span></p>          <p><span class="bodyGrey">First of all, let's agree upon terminology. We distinguish dependent and independent objects:            <b>dependent</b> objects are bounded to the parent object's lifecycle,            <b>independent</b> objects have independent lifecycle.            Thus, dependent objects are created/removed automatically, when their parent object is created/removed,            while all operations on independent objects should be performed explicitly.</span></p>          <p><span class="bodyGrey">However, with Castor 0.8.x you cannot describe explicitly the kind of object.            Instead, the following rule acts: if you have one-to-many relation, and each side of the relation            refers to another (Collection attribute on &quot;one&quot; side, simple attribute on &quot;many&quot; side),            then &quot;many&quot; side is a dependent object. All other objects are independent.            In particular, related objects via one-to-one relation are not created/removed automatically.</span></p>          <p><span class="bodyGrey">With Castor 0.9 dependent objects should be described via &quot;depends&quot; attribute of &quot;class&quot; element in mapping configuration file.</span></p>          <p><span class="bodyGrey">If you wish some independent object was created and/or removed automatically on operations on other independent object,            you may use interface Persistent to code the desired behavior.</span></p>            <p><span class="bodyGrey"><b>Is Castor JDO using any connection pooling mechanism to improve the overall performance ?</b></span></p>          <p><span class="bodyGrey">No, Castor JDO doesn't have any built-in JDBC resource pooling. However the         framework can transparently use any resource pooling facilities provided through         DataSource implementation of -even better- through JDNI. In fact we even recommend         people to use some Connection and PreparedStatement pool with Castor as this can         increase Castor's performance 3-5 fold.</span></p>          <p><span class="bodyGrey">For example the following set of statements :         <span class="bodyBlack"><pre>
        db.begin();
        db.execute(...)
        db.commit()
        </pre></span>         will be executed in much less time with the resource pooling because it will avoid creating         a new physical JDBC connection at every execution.</span></p>            <p><span class="bodyGrey">With Oracle, instead of specifying the usual JDBC driver you can use a         DataSource that specifically provides some Connection caching/pooling.</span></p>          <p><span class="bodyGrey">Thus if your jdo config file looks like :         <span class="bodyBlack"><pre>
        &lt;database name=&quot;...&quot; engine=&quot;oracle&quot; &gt;
            &lt;driver class-name=&quot;oracle.jdbc.driver.OracleDriver&quot;
                    url=&quot;jdbc:oracle:thin:@localhost:1521:TEST&quot; &gt;
                &lt;param name=&quot;user&quot; value=&quot;SYSTEM&quot;/&gt;
                &lt;param name=&quot;password&quot; value=&quot;manager&quot;/&gt;
            &lt;/driver&gt;
            ...
        &lt;/database&gt;
        </pre></span>         then it can be changed into (for example):         <span class="bodyBlack"><pre>
        &lt;database name=&quot;...&quot; engine=&quot;oracle&quot; &gt;
            &lt;driver URL=&quot;jdbc:oracle:thin:@localhost:1521:TEST&quot; 
                    class-name=&quot;oracle.jdbc.pool.OracleConnectionCacheImpl&quot;&gt;
                &lt;param name=&quot;user&quot; value=&quot;SYSTEM&quot; /&gt;
                &lt;param name=&quot;password&quot; value=&quot;manager&quot;/&gt;
            &lt;/driver&gt;
            ...
        &lt;/database&gt;
        </pre></span>         </span></p>          <p><span class="bodyGrey">When Castor is used inside a Container such as an EJB container (within BMP         or Session Bean), then the Container usually provides the JDBC Resource         through the JNDI ENC, which implicitely includes pooling facilities.</span></p>            <p><span class="bodyGrey"><b>I am getting ClassNotFoundException for my JDO class, but it is in the class path. Why?</b></span></p>          <p><span class="bodyGrey">Probably castor.jar file is in jre/lib/ext directory. In this case you should call          <span class="bodyBlack"><pre>
  jdo.setClassLoader(getClass().getClassLoader());
         </pre></span>        before jdo.getDatabase().</span></p>            <p><span class="bodyGrey"><b>I am getting exception &quot;the class ... is not persistence capable...&quot;. Why?</b></span></p>          <p><span class="bodyGrey">In this case as well as in many others you can get more information with the help of logging. Call</span></p>         <span class="bodyBlack"><pre>
  jdo.setLogWriter(Logger.getSystemLogger());
        </pre></span>         <p><span class="bodyGrey">and seek in the output for warnings and errors.</span></p>            <p><span class="bodyGrey"><b>I call db.remove() on the dependent object and commit, but this doesn't work...</b></span></p>          <p><span class="bodyGrey">You should not add/remove dependent objects directly. In order to add/remove the dependent object you should just add/remove it from the collection in the master object and call db.commit()</span></p>          <p><span class="bodyGrey">Dependent object cannot be created/removed explicitly. It's created automatically when it is added to a master object, and removed automatically when it de-linked/dereferenced from a master object.</span></p>          <p><span class="bodyGrey">Otherwise, we will be ran into problem like: a dependent object created explicitly but removed implicitly (delinked from a master object), or vice versa. It can also lead to other problems that are harder to detect.</span></p>            <p><span class="bodyGrey"><b>How should I represent string/date/boolean literals in OQL query?</b></span></p>          <p><span class="bodyGrey">It is recommended to replace literals with parameters and to set them via OQLQuery.bind(), for example:</span></p>          <span class="bodyBlack"><pre>
  OQLQuery query = db.getOQLQuery(&quot;SELECT p FROM Person p &quot;
        +&quot;WHERE name LIKE $1 AND dob&gt;$2 AND married=$3&quot;);
  query.bind(&quot;John %&quot;);
  query.bind((new SimpleDateFormat(&quot;yyyy-MM-dd&quot;))
        .parse(&quot;1960-01-01&quot;));
  query.bind(false);
         </pre></span>          <p><span class="bodyGrey"><b>Sometimes long transaction fails: on update() it is thrown ObjectModifiedException. Why?</b></span></p>          <p><span class="bodyGrey">Most probably the object that is being updated has more than 100 related objects of one class         and the cache size for this class is not enough. You should either increase the size of the cache         or change the cache type to time-limited (the default cache type is count-limited, the default size is 100),         for example:         <span class="bodyBlack"><pre>
  &lt;class ...&gt;
    &lt;cache-type type=&quot;count-limited&quot; capacity=&quot;1000&quot;/&gt;
    ...
  &lt;/class&gt;
        </pre></span>         </span></p>          <p><span class="bodyGrey"><b>I get &quot;java.lang.AbstractMethodError: getBigDecimal&quot; for numeric fields. Why?</b></span></p>          <p><span class="bodyGrey">Your JDBC driver is not JDBC 2.0 compliant, upgrade it or find another one.</span></p>          <a name="bi-directional"></a>         <p><span class="bodyGrey"><b>Does Castor support both one-way and two-way relationships?</b></span></p>          <p><span class="bodyGrey">         Typcially a relationship between two objects is either one-way (aka uni-directional)          or two-way (aka bi-directional). Officially, Castor currently only supports bi-directional          relationships. For example, if an <tt>Order</tt> object contains a reference to a          <tt>LineItem</tt> object, the <tt>LineItem</tt> object must contain a reference          to the Order object. However, this requirement is not enforced in all situations.          </span></p>                  <p><span class="bodyGrey">         This is a very complex problem to solve. So until Castor is expanded the support          uni-directional relationships, the best policy is to implement the bi-directionalality          for all relationships. This will ensure proper functionality.         </span></p>          <p><span class="bodyGrey"><b>I have an object that holds a relation to itself. Does Castor support this?</b></span></p>          <p><span class="bodyGrey">         This is a very common occurrence in an object model and is known as a self-referenential         relationship. Unfortunately, Castor does not currently support self-referential          relationships. An example of such a relationship occurs when a <tt>Folder</tt> object         contains a reference to another <tt>Folder</tt> object. Castor does not currently         support this. However, there are ways around this limitation.          </span></p>                  <p><span class="bodyGrey">         One way is to manage this type of relationship manually. For example, let's say that a         parent object <tt>FolderA</tt> needs to hold references to child objects <tt>FolderB</tt>,          <tt>FolderC</tt> and <tt>FolderD</tt>. The <tt>Folder</tt> object contains not only          a property to hold its own id, but also a property to hold its parent id (we'll call          this <tt>parentId</tt>).  The <tt>parentId</tt> property is used to determine if          there is a relationship to another <tt>Folder</tt> object. If <tt>parentId</tt> is          null, there is no relationship.  If <tt>parentId</tt> is populated, there is a          relationship and the object tree can be walked by comparing the object id to the          <tt>parentId</tt>. When the two properties are equal, you're at the top of the tree.          </span></p>          <p><span class="bodyGrey">         Another say to solve this problem is to make use of an intermediary object. For          example, a <tt>Folder</tt> object contains a <tt>Reference</tt> object in lieu of         the actual <tt>Folder</tt> object. The <tt>Reference</tt> object is somewhat of a         proxy object whereby it only contains enough information to identify the object         to which the <tt>Reference</tt> object refers. Then the <tt>Folder</tt> object         can be easily instantiated via the information contained in the <tt>Reference</tt>         object.          </span></p>          <p><span class="bodyGrey"><b>Why do I get an <tt>ObjectModifiedException</tt> when trying to commit a transaction ?</b></span></p>          <p><span class="bodyGrey">         The dirty checking engine will throw an <tt>ObjectModifiedException</tt> when the values         in the cache and in the database are different. This can happen when someone         else changed the database content, but also when type mapping is not reversible.         </span></p>          <p><span class="bodyGrey">         For example, if a java timestamp (java.util.Date) is stored as a DATE, the time         part is lost and the dirty checking will fail. Oracle can not tell the difference         between an empty String and a null value : if an attribute value is an empty String,         dirty checking will also fail. Some precision loss sometimes occur with floating point         numbers.         </span></p>          <p><span class="bodyGrey">         To avoid this, always use reversible mapping conversions. If this is not possible,         mark the fields with <tt>dirty=&quot;ignore&quot;</tt> in the mapping file.         </span></p>     <a name="OQL"><h2>OQL</h2></a>         <p><span class="bodyGrey"><b>Is there any document available for Castor OQL</b></span></p>          <p><span class="bodyGrey">Yes. It is available from the Castor website: <a href="oql.html">Advanced JDO --&gt; OQL</a></span></p>          <p><span class="bodyGrey"><b>The OQL document describes several phases of development. Which is the current phase?</b></span></p>         <p><span class="bodyGrey">We are currently working on Phase 3</span></p>          <p><span class="bodyGrey"><b>Does Castor OQL support sub queries</b></span></p>         <p><span class="bodyGrey">Not yet</span></p>          <p><span class="bodyGrey"><b>I cannot get Castor OQL to join two objects for me. Is it supported?</b></span></p>          <p><span class="bodyGrey">Yes or no. Castor OQL supports implicit joins. And, in most case, you simply don't need explicit join.</span></p>          <p><span class="bodyGrey">Consider the following example,          <span class="bodyBlack"><pre>
    SELECT o FROM Order o, LineItem i
            WHERE o.id = i.id AND i.price &gt; 100
        </pre></span></span></p>         <p><span class="bodyGrey">It is simply equivalent to the following OQL         <span class="bodyBlack"><pre>
    SELECT o FROM Order o,
            WHERE o.lineItem.price &gt; 100
        </pre></span></span></p>          <p><span class="bodyGrey"><b>Can I write a pass-thru OQL?</b></span></p>         <p><span class="bodyGrey">Yes. Just put &quot;CALL SQL&quot; in front of your SQL statement.</span></p>         <p><span class="bodyGrey">For example,         <span class="bodyBlack"><pre>
    OQLQuery oql = castorDb.getOQLQuery(
        &quot;CALL SQL SELECT id, name, date &quot;+
        &quot;FROM user WHERE upper(name) like $1 AS myapp.Product&quot;);
        </pre></span></span></p>         <p><span class="bodyGrey">Be remember that the order of the fields listed must match what is defined in the mapping file.</span></p>          <p><span class="bodyGrey"><b>Does Castor OQL support struct?</b></span></p>          <p><span class="bodyGrey">No, Castor OQL doesn't support struct. For example, the following query CANNOT be done: <span class="bodyBlack"><pre>
    select c.name, c.age from Client c
        </pre></span></span></p>          <p><span class="bodyGrey"><b>How do I structure a query using the 'LIKE' expression?</b></span></p>         <p><span class="bodyGrey">A query using the 'LIKE' expression includes the use of the SQL          wildcard '%'. The wildcard must be included in the <span class="bodyBlack"><pre>bind()</pre></span> statement:         <span class="bodyBlack"><pre>
    OQLQuery oql = castorDb.getOQLQuery( &quot;SELECT p FROM Product p WHERE p.name LIKE $1&quot; );
    oql.bind( &quot;%widget%&quot; );
        </pre></span>         </span></p>          <p><span class="bodyGrey"><b>Does Castor support the SQL 'IN' expression?</b></span></p>         <p><span class="bodyGrey">Yes. However, the full expression is a bit different using the LIST keyword.          The following example provides a demonstration:</span></p>         <p><span class="bodyGrey">         <span class="bodyBlack"><pre>
    SELECT p FROM Product p WHERE p.id IN LIST ( 123, 456, 789 )
        </pre></span>         </span></p>         <p><span class="bodyGrey">If identifiers other than numbers are used, those identifiers must be quoted:</span></p>         <p><span class="bodyGrey">         <span class="bodyBlack"><pre>
    SELECT p FROM Product p WHERE p.id IN LIST ( &quot;abc&quot;, &quot;jkl&quot;, &quot;xyz&quot; )
        </pre></span>         </span></p>      <a name="Features-requests"><h2>Features requests</h2></a>         <p><span class="bodyGrey"><b>Can a foreign key be part of multiple primary keys?</b></span></p>          <p><span class="bodyGrey">Unfortunately, the answer is no. We're aware of that many users request it. It is now very high priority in our Todo list.</span></p>          <p><span class="bodyGrey">If foreign key is the primary key, then user may consider to work around it using extend relationship.</span></p>          <p><span class="bodyGrey"><b>Is polymorphic collection supported?</b></span></p>          <p><span class="bodyGrey">Unfortunately, the answer is no</span></p>                  <p><span class="bodyGrey">In version 0.8.11, we tried to enable polymorphic collection by introducing the notation of Object Reloading. Object Reloading delegates the determination of the class to a data object. However, it is proved that reloading can only be done before any instance of the target object is returned to user, and we have no way to determine that. As a result, we removed the support in version 0.9.x.</span></p>                  <p><span class="bodyGrey">In the near future, we are going to use a new mechanism to provide extends. The new mechanism loads a table with an SQL statement that outer-joins all of the extending tables with the base. The existence of an extended table row can be used to determine the class of a data object. Notice that all extended table rows of the same entity should always be stored in the same data-store. </span></p>          <p><span class="bodyGrey">In the further future, we also want to let users to define a discriminator column (or determinance field). Basing on the value of discriminator columns in the base table, the bridge layer fetches the additional information and returns the combined entity with the appropriate list of entity classes.</span></p>       <a name="Data-model-issues"><h2>Data model issues</h2></a>         <p><span class="bodyGrey"><b>Is it possible to map an object to more than one tables?</b></span></p>          <p><span class="bodyGrey">Yes, if the two tables share the same identity, you can specify one data object to &quot;extends&quot; the other. When the extended data object is loaded, its table (specified in &lt;map-to/&gt; will be joined with all the tables of its super classes'.</span></p>          <p><span class="bodyGrey">Another solution (in my opinion more flexible) is having two set of methods in the main object. One for Castor JDO and another for application.</span></p>          <p><span class="bodyGrey">Consider the following example:         <span class="bodyBlack"><pre>
        class Employee {
           private int _employeeNumber;
           private Address _address;
           private Collection _workGroup;

           public int getEmployeeNumber() {
                return _employeeNumber;
           }
           public void setEmployeeNumber( int id ) {
                _employeeNumber = id;
           }

           // methods for Castor JDO
           public Address getAddress() {
               return _address;
           }
           public void setAddress( Address address ) {
                _address = address;
           }
           public Collection getWorkGroup() {
                return _workGroup;
           }
           public Collection setWorkGroup( Collection workGroup ) {
                _workGroup = workGroup;
           }

           // methods for application
           public String getAddressCity() {
               return _address.getCity();
           }
           public String getAddressZip() {
               return _address.getZip();
           }
           // ...
        }
        </pre></span></span></p>            <p><span class="bodyGrey"><b>Can an object with the same identity be re-created after being removed in the same transaction?</b></span></p>          <p><span class="bodyGrey">Yes, as long as the deleted object is the same instance as the one being recreated.</span></p>            <p><span class="bodyGrey"><b>What does &quot;dependent object&quot; means, really?</b></span></p>          <p><span class="bodyGrey">Dependent object is actually a concept from the object-oriented database world:</span></p>          <p><span class="bodyGrey">Dependent object's lifetime is depends on its master object. So, create/delete/update of the master object will trigger the proper actions, newly linked dependent object will be automatically created and de-referenced dependent object will be removed.</span></p>          <p><span class="bodyGrey">The concept was also used in the earlier CMP 2.0 draft, although it is later removed.</span></p>            <p><span class="bodyGrey"><b>Can data object involves in many-to-many relationship be dependent</b></span></p>          <p><span class="bodyGrey">No</span></p>       <a name="Castor-JDO-design"><h2>Castor JDO design</h2></a>         <p><span class="bodyGrey"><b>How does Castor JDO work anyway?</b></span></p>          <p><span class="bodyGrey">Let's use object loading as an example.</span></p>          <p><span class="bodyGrey">When an application invoke db.load, the underneath TransactionContext is invoked. If the object with the requested identity exists in the TransactionContext, previously loaded object in the TransactionContext is returned. Otherwise, TransactionContext creates a new instance of the interested type and invokes LockEngine to &quot;fill&quot; the object. </span></p>          <p><span class="bodyGrey">LockEngine acquires a lock of the object, and it makes sure ClassMolder has a thread-safe environment when it invokes ClassMolder. In ClassMolder, if the interested set of fields representing the object is not existed in the cache yet, SQLEngine will be invoked and the set of fields from the underneath data store will be returned. ClassMolder binds the loaded or cached fields into the new instance. ClassMolder requests the TransactionContext to load the related and the dependent objects. Eventually, the object is returned after all of the relationships are resolved.</span></p>          <p><span class="bodyGrey">The process of commit has several states. The first state is preStore. In preStore state, objects existing in the TransactionContext are checked for modification one by one, including dependent and related objects. De-referenced dependent objects are marked as delete-able, and reachable dependent objects are added into TransactionContext. An object is marked &quot;dirty&quot; if it is modified. Also, if any modification should cause any related or dependent to be dirty, the related or dependent object is marked as dirty as well. </span></p>          <p><span class="bodyGrey">After the preStore state, all dirty object is properly stored. And, all marked delete object will be removed. Then, the connection is committed. If succeed, all cache with be updated. Finally, all lock is released.</span></p>           <p><span class="bodyGrey"><b>Does Castor support two-phase commits?  How is this implemented?</b></span></p>          <p><span class="bodyGrey">Yes, via Synchronization interface.</span></p>          <p><span class="bodyGrey">TransactionManager must be bound to JNDI, its JNDI name should be passed to JDO object:</span></p>          <span class="bodyBlack"><pre>
        jdo.setTransactionManager(jndiName);
        db = jdo.getDatabase();
        </pre></span>          <p><span class="bodyGrey">Database implementation also implements Synchronization and is authomatically registered with the transaction manager.</span></p>          <p><span class="bodyGrey">Then TM communicates with Castor via beforeCompletion() and afterCompletion() calls.</span></p>           <p><span class="bodyGrey"><b>Does Castor support nested transaction?</b></span></p>          <p><span class="bodyGrey">No</span></p>       <a name="Working-with-open-source-databases"><h2>Working with open source databases</h2></a>         <p><span class="bodyGrey"><b>Does Castor support PosgreSQL?</b></span></p>          <p><span class="bodyGrey">Yes, starting from PostgreSQL 7.1, where outer joins support has been added.</span></p>          <p><span class="bodyGrey"><b>Does Castor support MySQL?</b></span></p>          <p><span class="bodyGrey">Yes, starting from MySQL version 3.23, where transaction support has been added.            Note: if you use mm.MySQL JDBC driver, then you need version 2.0.3 or higher.</span></p>          <p><span class="bodyGrey"><b>Which open source database is supported better?</b></span></p>          <p><span class="bodyGrey">For now only with <a href="http://www.postgresql.org">PostgreSQL 7.1</a> and <a href="http://www.sapdb.org">SAP DB</a> you get a full set of Castor features. Other open source databases doesn't support select with write lock, so db-locked locking mode doesn't work properly (it works in the same way as exclusive locking mode).</span></p>          <p><span class="bodyGrey">All other Castor features are supported with <a href="http:/www.mysql.com">MySQL</a>, <a href="http://www.interbase2000.org">Interbase</a>, <a href="http://instantdb.enhydra.org">InstantDB</a> and <a href="http://www.hypersonicsql.com">Hypersonic SQL</a>.</span></p>     <a name="Integrating-Castor's-logging-with-Log4J"><h2>Integrating Castor's logging with Log4J</h2></a>         <p><span class="bodyGrey"><b>How can I integrate Castor's logging with a logging infrastructure using Log4J?</b></span></p>          <p><span class="bodyGrey">Please see <a href="http://www.mail-archive.com/castor-dev@exolab.org/msg02710.html">this message</a> from the mailing list. It includes an adapter class that will provide this functionality. (Thanks John!)</span></p>     <a name="Lazy-Loading-related-questions"><h2>Lazy Loading related questions</h2></a>         <p><span class="bodyGrey"><b>How do I configure the JDO mapping to use the lazy loading feature?</b>        </span></p>                 <p><span class="bodyGrey">        Let us convert one of the classes from the <a href="http://castor.exolab.org/examples.html">JDO examples</a> to use lazy-loading.        </span></p>         <p><span class="bodyGrey">        In the example model, one Product can contain many ProductDetails. This is reflected in the conventional mapping as below. First, the mapping for Product:               <span class="bodyBlack"><pre>
       
&lt;!--  Mapping for Product  --&gt;
&lt;class name=&quot;myapp.Product&quot;
       identity=&quot;id&quot;&gt;
   &lt;description&gt;Product definition&lt;/description&gt;
   &lt;map-to table=&quot;prod&quot; xml=&quot;product&quot; /&gt;
   &lt;field name=&quot;id&quot; type=&quot;integer&quot;&gt;
       &lt;sql name=&quot;id&quot; type=&quot;integer&quot; /&gt;
       &lt;xml name=&quot;id&quot; node=&quot;attribute&quot;/&gt;
   &lt;/field&gt;
 
   &lt;!-- more fields ... --&gt;

   &lt;!-- Product has reference to ProductDetail
            many details per product  --&gt;
   &lt;field name=&quot;details&quot; type=&quot;myapp.ProductDetail&quot; required=&quot;true&quot;
           collection=&quot;vector&quot;&gt;
       &lt;sql many-key=&quot;prod_id&quot;/&gt;
       &lt;xml name=&quot;detail&quot; node=&quot;element&quot; /&gt;
   &lt;/field&gt;
&lt;/class&gt;
           
       </pre></span>         </span></p>        <p><span class="bodyGrey">        Now let us examine ProductDetail. Note, the relationship is mapped <a href="#bi-directional">bi-directionally</a> as must be all relationships when using Castor JDO.        <span class="bodyBlack"><pre>
       
&lt;!--  Mapping for Product Detail --&gt;
&lt;class name=&quot;myapp.ProductDetail&quot; identity=&quot;id&quot; depends=&quot;myapp.Product&quot; &gt;
   &lt;description&gt;Product detail&lt;/description&gt;
    &lt;map-to table=&quot;prod_detail&quot; xml=&quot;detail&quot; /&gt;
   &lt;field name=&quot;id&quot; type=&quot;integer&quot;&gt;
       &lt;sql name=&quot;id&quot; type=&quot;integer&quot;/&gt;
       &lt;xml node=&quot;attribute&quot;/&gt;
    &lt;/field&gt;
    &lt;field name=&quot;product&quot; type=&quot;myapp.Product&quot;&gt;
       &lt;sql name=&quot;prod_id&quot; /&gt;
       &lt;xml name=&quot;product&quot; node=&quot;element&quot; /&gt;
    &lt;/field&gt;
   
       &lt;!-- more fields ... --&gt;
   
&lt;/class&gt;
       
       </pre></span>        </span></p>        <p><span class="bodyGrey">Let us now make the relationship between Product and ProductDetail use lazy loading. We need only change the way that the relationship to ProductDetail is specified in the mapping of Product. The relevant field in Product can be re-written like so:         <span class="bodyBlack"><pre>
       
&lt;field name=&quot;details&quot; type=&quot;myapp.ProductDetail&quot; required=&quot;true&quot; lazy=&quot;true&quot;
            collection=&quot;collection&quot;&gt;
   &lt;sql many-key=&quot;prod_id&quot;/&gt;
   &lt;xml name=&quot;detail&quot; node=&quot;element&quot; /&gt;
&lt;/field&gt;
       
       </pre></span>        </span></p>        <p><span class="bodyGrey">        There have been two changes.        <table border="0" cellpadding="2" cellspacing="2"><tr><td colspan="2" height="5"></td></tr><span class="bodyGrey">            <tr><td align="left" valign="top" width="10">-</td><td align="left" valign="top"><span class="bodyGrey">We have placed the attribute lazy=&quot;true&quot; in the field element</span></td></tr>            <tr><td align="left" valign="top" width="10">-</td><td align="left" valign="top"><span class="bodyGrey">We have changed the type of the underlying collection type to be a java.util.Collection by changing the field element attribute to collection=&quot;collection&quot;.</span></td></tr>        </span></table>                   </span></p>        <p><span class="bodyGrey">         Note that no change is required in the ProductDetail mapping.        </span></p>                 <p><span class="bodyGrey"><b>I have modified my mapping to use lazy loading. Now I get the error &quot;no method to set value for field: com.xyz.ClassB in class: ClassMolder com.xyz.ClassA&quot; or &quot;org.exolab.castor.jdo.DataObjectAccessException: no method to set value for field: com.xyz.ClassB in class: ClassMolder com.xyz.ClassA&quot;. What am I doing wrong?</b></span></p>                  <p><span class="bodyGrey">        To use lazy loading you must also change the persistent class that will hold the related objects. At the very highest level, you need to provide a set method that accepts a java.util.Collection for the field in question. This is demonstrated by changing the <a href="http://castor.exolab.org/examples.html">JDO examples</a> below.</span></p>         <p><span class="bodyGrey">        In the original Product class we have the following code         <span class="bodyBlack"><pre>
       
import java.util.Vector;
...
private Vector       _details = new Vector();
...
public Vector getDetails()
{
   return _details;
}


public void addDetail( ProductDetail detail )
{
   _details.add( detail );
   detail.setProduct( this );
}
       
       </pre></span>        </span></p>         <p><span class="bodyGrey">        Let us now make the necessary changes to set up lazy loading. As stated above we now require a special set method for the related ProductDetails (stored originally as a java.util.Vector) that accepts a java.util.Collection as an argument. This mandates that we must also use a java.util.Collection to hold our ProductDetails. If this is not added, you will receive the errors above.         <span class="bodyBlack"><pre>
       
import java.util.Collection;
...
private Collection       _details;
...
public Collection getDetails()
{
   return _details;
}


public void setDetails( Collection details )
{
   _details = details;
}

       
       </pre></span>        </span></p>                     <a name="Tuning-for-LOBs"><h2>Tuning for LOBs</h2></a>     <p><span class="bodyGrey">     Castor JDO provides a property in <tt>castor.properties</tt> for adjusting      the size of the JDBC driver's buffer for reading LOBs (BLOBs and CLOBs) from      the database. The propery is named <tt>org.exolab.castor.jdo.lobBufferSize</tt>      and its default is 5120 bytes (5k). The size of this buffer can be tuned     for larger LOBs, but is dependent upon the JDBC driver implementation being      used and what it supports.      </span></p>     </td></tr><tr height="5"><td width="10" height="5" bgcolor="#7270c2" valign="top" align="left">&nbsp;</td><td width="115" height="5" bgcolor="#7270c2" valign="top"><img src="images/dotTrans.gif" width="1" height="15" border="0"><br><img src="images/line_sm.gif" width="105" height="3" border="0" align="right"></td><td width="7" height="5" bgcolor="#a9a5de" valign="top" align="left">&nbsp;</td><td width="70" height="5" valign="top" align="left">&nbsp;</td><td width="120" height="5" valign="top" align="left">&nbsp;</td></tr><tr><td width="10" height="5" bgcolor="#7270c2" valign="top" align="left">&nbsp;</td><td width="115" bgcolor="#7270c2" valign="top" align="left"></td><td width="7" bgcolor="#a9a5de" valign="top" align="left"><img src="images/dotTrans.gif" width="1" height="25" border="0"></td><td width="70" valign="top" align="left"><img src="images/dotTrans.gif" width="1" height="25" border="0"></td><td width="120" valign="top" align="left">&nbsp;</td></tr><tr height="5"><td width="10" rowspan="2" height="100%" bgcolor="#7270c2" valign="bottom" align="left"><img src="images/stripes1.gif" width="10" height="125" border="0"></td><td width="115" rowspan="2" height="100%" bgcolor="#7270c2" valign="bottom" align="left"><img src="images/stripe105.gif" width="105" height="125" border="0"></td><td width="7" rowspan="2" height="100%" bgcolor="#a9a5de" valign="top" align="left">&nbsp;</td><td width="70" height="100%" valign="top" align="left">&nbsp;</td><td width="120" height="100%" valign="top" align="left">&nbsp;</td></tr><tr height="5"><td width="70" height="25" valign="top" align="left">&nbsp;</td><td width="400" height="25" valign="bottom" align="left"><br><br><img src="images/line_light.gif" border="0" width="400" height="3"><br><p></p><span class="bodyGrey"><small><notice>     Copyright ) 1999-2003 <a href="http://www.exolab.org">ExoLab Group</a>.  All rights reserved.   </notice><br>&nbsp;<br></small><small><notice>     Java, EJB, JDBC, JNDI, JTA, Sun, Sun Microsystems are trademarks or registered     trademarks of Sun Microsystems, Inc. in the United States and in other     countries. XML, XML Schema, XSLT and related standards are trademarks or registered     trademarks of MIT, INRIA, Keio or others, and a product of the World Wide Web     Consortium. All other product names mentioned herein are trademarks of their respective     owners.   </notice><br>&nbsp;<br></small></span><p></p>&nbsp;</td><td width="120" height="25" valign="top" align="left">&nbsp;</td></tr></table></body></html>