![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ||||||||||||||||||||||||||||||||||||||||
![]() | ![]() | ![]() | ![]() | ||||||||||||||||||||||||||||||||||||||||||
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ||||||||||||||||||||||||||||||||||||||||
![]() | ![]()
|
Castor's relation to other specifications XML related questions Technical questions Features requests Design issues Working with open source databases Castor's relation to other specificationsDoes Castor JDO comply with the SUN JSR-000012 specification? No, Castor JDO doesn't comply with the SUN's JDO specification. Although Castor JDO carries very similar goals as SUN's JDO, it has been developed independently from the JSR. Although it is not impossible to shape (perhaps "hammer" 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. 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. Castor also provides other features, such as key generators, long transaction support and OQL query which cannot be found in SUN's JSR. Is Castor JDO better than EJB CMP? The relation between JDO and EJB Bean is sometimes more complicated than simply saying, "one is better than the other". 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). 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. 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. If a developer would like to take advantage of EJB's life-cycle management, security, the "write once deploy anywhere" promise and other distributed business application facilities, then EJB will be the right choice. 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. XML related questionsIs it possible to make xml marshalling transactional using Castor? No. The decision of putting XML and JDO together is NOT intended to make XML marshalling transactional. 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. 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. Is it possible to do query on a XML file using Castor? 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. Technical questionsI have encountered problems using Sun JDBC-ODBC bridge with Castor... 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 > 1, or use some other JDBC-ODBC bridge without such restriction (for example, from Easysoft). My get-method for the Collection of dependent objects returns null. Why? You should initialize the Collection yourself: Should my JDO classes implement some special interface? 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. Can Castor automatically create/remove related objects? First of all, let's agree upon terminology. We distinguish dependent and independent objects: dependent objects are bounded to the parent object's lifecycle, independent 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. 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 "one" side, simple attribute on "many" side), then "many" side is a dependent object. All other objects are independent. In particular, related objects via one-to-one relation are not created/removed automatically. With Castor 0.9 dependent objects should be described via "depends" attribute of "class" element in mapping configuration file. 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. Is Castor JDO using any connection pooling mechanism to improve the overall performance ? 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. For example the following set of statements : With Oracle, instead of specifying the usual JDBC driver you can use a DataSource that specifically provides some Connection caching/pooling. Thus if your jdo config file looks like : 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. I am getting ClassNotFoundException for my JDO class, but it is in the class path. Why? Probably castor.jar file is in jre/lib/ext directory. In this case you should call I am getting exception "the class ... is not persistence capable...". Why? In this case as well as in many others you can get more information with the help of logging. Call jdo.setLogWriter(Logger.getSystemLogger()); and seek in the output for warnings and errors. I call db.remove() on the dependent object and commit, but this doesn't work... 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() How should I represent string/date/boolean literals in OQL query? It is recommended to replace literals with parameters and to set them via OQLQuery.bind(), for example: OQLQuery query = db.getOQLQuery("SELECT p FROM Person p WHERE name LIKE $1 AND dob>$2 AND married=$3"); query.bind("John %"); query.bind((new SimpleDateFormat("yyyy-MM-dd")).parse("1960-01-01")); query.bind(false); Sometimes long transaction fails: on update() it is thrown ObjectModifiedException. Why? 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: I get "java.lang.AbstractMethodError: getBigDecimal" for numeric fields. Why? Your JDBC driver is not JDBC 2.0 compliant, upgrade it or find another one. Features requestsCan a foreign key be part of multiple primary keys? Unfortunately, the answer is no. We're awared that many users request it. It is now very high prority in our Todo list. If foreign key is the primary key, then user may consider to work around it using extend relationship. Is polymorphic collection supported? Unfortunaely, the answer is no 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. Outer-join all extending tables. As a result, we removed the support in version 0.9.x. 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. 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. More about discriminator field is discussed in Part II of this document. Design issuesHow does Castor JDO work anyway? Let's use object loading as an example. 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 "fill" the object. 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. 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 "dirty" 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. 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. Does Castor support two-phase commits? How is this implemented? Yes, via Synchronization interface. TransactionManager must be bound to JNDI, its JNDI name should be passed to JDO object: jdo.setTransactionManager(jndiName); db = jdo.getDatabase(); Database implementation also implements Synchronization and is authomatically registered with the transaction manager. Then TM communicates with Castor via beforeCompletion() and afterCompletion() calls. Working with open source databasesDoes Castor support PosgreSQL? Yes, starting from PostgreSQL 7.1, where outer joins support has been added. Does Castor support MySQL? 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. Which open source database is supported better? For now only with PostgreSQL 7.1 and SAP DB 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). All other Castor features are supported with MySQL, Interbase, InstantDB and Hypersonic SQL. | |||||||||||||||||||||||||||||||||||||||||||
![]() ![]() | |||||||||||||||||||||||||||||||||||||||||||||
![]() | ![]() | ||||||||||||||||||||||||||||||||||||||||||||
![]() | ![]() | ||||||||||||||||||||||||||||||||||||||||||||
![]() |