Q:I seem to be able to create db objects within other db objects with calls to new, rather than to createObject() but their behaviour seems erratic. Is this supposed to work or is it inadvisable?
A:Calling new does not create a database object. However, not all persistent classes have to be database classes. A Car class may have a string member: name. This name object is persistent and will be stored in the database but it is not a database object because no other than the Car object can access it.
Q:Do all persistent objects need to be created by calling the no-parameter, no-body constructor? or can you call another constructor?
A:There is a createObject method that calls other then the default constructors. But it needs some more work because it needs the signature of the constructor as string. Maybe someone can help and write some lines of code to generate the signature out of the parameter objects.
Q:What is the difference between creating objects from outside the db server and creating them from within the db server?
A:The result of both operations is the same. But creating a database object from another database object is much faster than from the client. And, if you are creating more than one objects at the same time, doing this inside a database method encloses all the create operations inside a transaction (without the need to explicitely mark transaction boundaries) which is most likely wanted.
Q:Am I right in thinking that if you create an object with database().createObject(), the constructor of myObject can't create other objects - I get an "object is not yet associated to a database container" exception.
A:Yes, you are right. Therefore, although it doesn't look that nice, an initialization method could be used.
A:Another way is to use the callback method onCreate() to get around this problem as this method is called after container association.
Example: public void onCreate() throws Exception { OzoneInterface ob = this.database(); this.address = (Address)ob.createObject(AddressImpl.class.getName()); this.employees = (People)ob.createObject(PeopleImpl.class.getName()); this.customers = (People)ob.createObject(PeopleImpl.class.getName()); }
A:Yes, onDelete() should be added to remove objects that are considered "Contained" by the object. In other words, no other objects should reference them. This will help the referencial integrity of the system by not leaving unreferenced "garbage" objects.
Q:If I have a database object which has an attribute that has a list of ordinary serializable objects, does the list gets loaded when I access one of these Objects?
A:If you use the normal Java collections then, yes, the complete collection gets loaded into the memory since ozone works with Java serialization.
Q:That would be a problem as the list could be quite large and loading it would require lots of RAM. How do you suggest I design this in order to minimize redundancy and memory consumption?
A:The solution is using a collection of persistent objects, e.g. a linked list where each list node is a database object. Then the list nodes are loaded and removed on demand. That slows down the performance but saves memory.
A:adding/removing method and adding of members works. See jdk doc about serialization and serialVersionUID.
If you make your database objects 'Externalizable' and implement read/writeExternal clever you can do a pretty good schema evolution. You can then use a version number (not serialVersionUID !), write it in writeExternal, check it within readExternal and do additional actions if the version number has a particular value. Thus you can avoid the normal serialization schema evolution limitations, e.g. removing a member. The serialVersionUID stays always the same. Because of this Java thinks the streamed objects are always compatible to the current implementation. The second version number is for you to control which version you've got serialized.
An Example:
public class TestImpl extends OzoneObject implements Test, Externalizable { // remains always 1 static long serialVersionUID = 1L; // increase it if you added or removed a member static int subSerialVersionUID = 2L; // is member since version 1 private String aMember; // a new member private HashMap bMember; // ... some methods ... public void writeExternal( ObjectOutput out ) throws IOException { out.writeInt( subSerialVersionUID ); out.writeObject( aMember ); out.writeObject( bMember ); } public void readExternal( ObjectInput in ) throws IOException { int version = in.readInt(); aMember = (String)in.readObject(); if (version == 1) { // a deleted member from version 1 in.readObject(); } if (version > 1) { bMember = (HashMap)in.readObject(); } } }
Q:How would I go about retrieving the object with the oldest creationDate attribute? Also, is it possible to retrieve an object or a set of objects based on the exact attribute value (e.g. all cars made in 1974)? Similarly, is it possible to retrieve an object or a set of objects bases on the range of values (e.g. all cars made between 1974 and 1984)?
A:There is no descriptive query system yet. There are two possibilities:
your queries are not that complex; in this case you can Java-code the queries. i.e. you start at the named root objects and than traverse the path to the objects you need as you would do it in a usual Java program.
the queries are complex; in this case you can start an effort to finally make a descriptive query system for ozone ;)
Q:Say we have the query "Select name from table where name=manav". How can i do the equivalentthings in Ozone? I.e. how can I perform QUERY Like things in OZONE such as Select,Delete,Update etc.
A:Object databases are very different from relational db's. You manipulate data through the methods defined by your persistant objects. Simply put: UPDATE will probably be a set method, SELECT will probably be a get method etc. so you need to implement your own queryable data structure in the Java objects stored inside Ozone.
For an example of a fairly general and slightly eccentric form of searchable and indexable data structure, see Reasons com.twilightminds.jdf.data and com.twilightminds.jdf.data.ozone packages here, and a introductory guide to same here.
Q:Can you point me to any documentation that might describe how best to adjust the cluster size, table size, etc. for best performance?
A:cluster size does not affect performance that much. But the size of the object cache (JVM heap size) and the dimension of the B-tree caches are very important. The Admin documentation or Server Configuration should help you to get started with this. You should always try to adjust cache and table sizes so that the _working set_ of your data is kept 'in cache'. That is, all objects of your working set of data should fit in memory and the B-tree tableBufferSize should be <= the number of objects in your working set.