Guide  Reference  Contents  Previous  Next  Index
This chapter provides an introduction to Objectivity for Java, the Java programming interface to the Objectivity/DB object-oriented database management system. The rest of this guide provides detailed conceptual information about Objectivity/DB features and how they are accessed through the Objectivity for Java programming interface. See the Objectivity for Java Reference for a complete description of all the classes and interfaces in Objectivity for Java.
This section gives an overview of the components of an Objectivity for Java application:
An Objectivity/DB application works with objects stored in Objectivity/DB databases. In the Objectivity/DB architecture, Objectivity/DB applications have database services built directly into the application instead of relying on a back-end server process. This is accomplished by dynamically loading Objectivity/DB libraries into the same process space as the application.
Objectivity/DB provides simultaneous, multiuser access to databases that can be distributed across a network. A group of such databases is organized into a unit, called a federated database, by Objectivity/DB. All the logical entities in Objectivity/DB, including the federation, are called Objectivity/DB objects.
Applications do not work with Objectivity/DB objects directly; instead they work with local representations of objects, which must be retrieved from and written back to a federated database. To ensure that data maintained by Objectivity/DB objects remains consistent while being used by competing applications, Objectivity/DB uses a system of permissions, called read locks and write locks, to control access to the objects.
Locks are administered by a lock server that can run on any machine in the network. Before an operation can be performed on an Objectivity/DB object, an application must obtain access rights to the object from the lock server. In a standard configuration, the lock server runs as a separate process from the applications that consult it. If all lock requests originate from a single, multithreaded application, that application can optionally start its own internal lock server using a separately purchased option to Objectivity/DB, namely, Objectivity/DB In-Process Lock Server Option (Objectivity/IPLS). See Chapter 18, "In-Process Lock Server".
An application's access to Objectivity/DB objects is controlled by a transaction. Transactions control the locks acquired on behalf of an application, and the transfer of data between the local representation of Objectivity/DB objects and the objects in a federated database.
A transaction is effectively a subsection of an application, the extent of which is designated by four operations: begin, commit, checkpoint, and abort. Once an application begins a transaction, the application can obtain access rights to, and local representations of, Objectivity/DB objects. From this point, the application is said to be within a transaction. A transaction ends when it is committed or aborted. The locks on any Objectivity/DB objects are released, the local representations of Objectivity/DB objects may no longer be consistent with the objects in the federated database, and invoking a system-defined operation on an Objectivity/DB object will throw a TransactionNotInProgressException.
When the application commits the transaction, any modifications to the objects are stored in the federated database. If the application aborts the transaction instead of committing it, the changes are discarded (rolled back), leaving the federated database in the logical state it was in before the transaction started. An application can also checkpoint a transaction, which saves modifications to the federated database but retains the local representations of objects and their locks.
Objectivity/DB guarantees that certain properties--atomicity, consistency, isolation, and durability (denoted by the acronym ACID)--are maintained when the operations within a transaction are applied to a database.
Atomicity means that all the operations within a transaction are performed on the database or none is performed. Thus, several operations, on one or more of the objects contained in a database, appear to all users as a single, indivisible operation.
Consistency means that the transaction takes the database from one internally consistent state to another, even though intermediate steps of the transaction may leave the objects in an inconsistent state. This property is dependent on the atomicity property.
Isolation means that until the transaction commits, any changes made to objects are visible only to other operations within the same transaction. When a transaction commits, the changes are made permanent in the database and henceforth visible to any other concurrent users of the database. If the transaction aborts, none of the changes are made permanent in the database.
Durability means that the effects of committed transactions are preserved in the event of system failures such as crashes or memory exhaustion.
There are four types of Objectivity/DB objects: basic object, container, database, and federated database.
A basic object is the fundamental unit stored by Objectivity/DB. An object whose class is defined by your application is maintained by Objectivity/DB as a basic object. Each basic object is contained within a container.
Containers serve a number of purposes within Objectivity/DB. They are used:
Each container is contained within a database.
A database consists of system-created containers and containers created by your application. A database is physically maintained as a file and is used to distribute related containers and basic objects to a particular physical location. Each database is contained within a federated database.
A federated database consists of system-created databases and databases created by your application. The federated database maintains the object model (or schema) that describes all the objects stored in the databases. The schema is language independent, which means that objects of classes defined using the Objectivity for Java programming interface can be accessed and managed from other Objectivity/DB programming interfaces.
A federated database is the unit of administrative control for Objectivity/DB. A federated database maintains configuration information (where Objectivity/DB files physically reside) and all recovery and backup operations are performed at the federated database level.
Objectivity/DB objects are organized into a containment or storage hierarchy:
federated database<databases<containers<basic objects.
In Objectivity/DB, the objects (federated database, database, and container) that contain other objects are called storage objects. Storage objects group other objects to achieve performance, space utilization, and concurrency requirements. The behavior of storage objects is defined solely by Objectivity/DB.
Objects that represent persistent data are called persistent objects. The behavior of persistent objects is defined by Objectivity/DB and your application. Basic objects are persistent objects. If you choose to associate application-specific data with a container, such a container will function as a persistent object as well as a storage object.
Besides the basic object life-cycle operations of creation, deletion, and property management, Objectivity/DB objects provide additional operations to support their transfer between an application and a federated database.
In Objectivity for Java, persistent objects (including containers) are initially created as transient Java objects. An application must perform a specific operation called clustering that causes a transient object to be assigned a storage location in a database. Databases are always persistent and do not have to be clustered. For both persistent objects and databases, the assignment is not permanent until the transaction in which the assignment occurred commits.
Once an object exists within Objectivity/DB, you need to perform the following steps before you can access the object:
Because of the different role of storage and persistent objects, these operations are provided by slightly different mechanisms, and are subject to different policies for the different types of objects. The mechanisms and policies, as well as the basic object life-cycle management operations, are discussed in the following sections.
You can create and delete storage objects in two ways:
The following table summarizes the operations available for each kind of storage object:
API (create and delete) | Tool (create and delete) | |
Container | X | |
Database | X | X |
Federated Database | X |
Deleting a storage object deletes all of the objects contained in it.
All storage objects are given identifiers when they are created. The federated database identifier is an integer, specified by the creator of the federated database.
Databases and containers also have integer identifiers. Typically these are assigned by Objectivity/DB when either type of object is created. The creator of a database, however, has the option of specifying its identifier.
Storage object identifiers are used to identify their respective objects to the lock server. The identifiers of a database and container appear as components of the identifiers of the persistent objects stored within them.
A system name uniquely identifies a storage object to Objectivity/DB. System names are mandatory for federated databases and databases and are optional for containers. System names have the following characteristics:
You can retrieve a preexisting storage object by:
Whenever you perform an operation on a storage object, Objectivity/DB will implicitly obtain the locks needed by your application at the point at which they are needed. For example, when you create a new container in a database, Objectivity/DB will get a write lock on the new container and the database.
You may also explicitly request a lock in advance of actually using the object, to ensure that you will not be prevented from getting a lock because the object has been locked by another application.
When a federated database or database is locked implicitly, it can be shared. The role of the lock in this situation is not to control access, but to instruct Objectivity/DB to record modifications to the object in the transaction's journal file. Objectivity/DB uses the journal file to restore a federated database to its previous state if the transaction is aborted or terminated abnormally. In contrast, when a federated database or database is locked explicitly, it can be used only by the locking application. A write lock prevents all other concurrent access, and a read lock prevents another application from modifying the locked object.
Containers are the most visible unit of locking for users of persistent objects. When any basic object in a container is locked, the entire container is locked, effectively locking all basic objects in the container. Whenever a lock is requested for a container, Objectivity/DB applies a concurrent access policy to determine whether the requested lock is compatible with any existing locks.
Whenever a lock on a container is requested, a concurrent access policy is applied to determine whether the lock should be granted. Objectivity/DB supports two concurrent access policies: exclusive and MROW.
The exclusive concurrent access policy rules are:
The multiple readers, one writer (MROW) policy is useful for applications that would rather access a potentially out-of-date object than be prevented from accessing the object at all. MROW is used to allow access to the last committed or checkpointed version of a container being updated by another application.
The MROW concurrent access rules are:
A persistent object is the representation of an object within an Objectivity/DB federated database. Both basic objects and containers can maintain application-specific data, and thus can serve as persistent objects.
A persistent object is an instance of a persistence-capable class.
The first step in developing an object-oriented application is to define the classes that capture the structure and behavior of the fundamental entities in the application. Such definitions usually arise naturally out of the logical modeling phase of application development. With classes whose instances will be persistent, two additional steps must be added to the definition process:
One of the defining characteristics of object-oriented databases is that persistent objects are accessible in a natural fashion from object-oriented programming languages. In order for this to be possible, persistence behavior must be associated with classes previously capable of producing only transient objects. In Objectivity for Java, the developer must explicitly add persistence behavior to application classes by deriving from a specific superclass, or by having the application class implement a simple interface. The classes with persistence behavior are said to be persistence capable. In addition to transient and persistence-capable classes, Objectivity for Java also supports non-persistence-capable classes, which are classes that cannot be used to create persistent objects directly. Objects of these classes are stored in the federated database when they are used as attributes of persistence-capable classes. An example of a non-persistence-capable class is the String class.
Defining a persistence-capable class is very similar to defining a class used to create objects only within the application. In particular, classes whose instances are stored by Objectivity/DB may contain any of the following types of data:
Objectivity/DB also provides a number of capabilities for modeling links or relationships between objects, enabling a higher level of functionality than simply using references to related objects. You can specify the directionality and cardinality of relationships, how relationships are handled when objects are copied or versioned, and whether operations on objects propagate along relationships.
Once the class definitions are complete, they must be added to the federated database's schema. In Objectivity for Java, classes are added implicitly when objects are made persistent, or explicitly through schema management methods in the programming interface.
At creation time, both containers and basic objects are transient and must be made persistent. There are two mechanisms for making a transient object persistent:
Note that even though an object is persistent after one of these operations, the object is not visible to other transactions until the transaction in which it was made persistent commits or checkpoints.
The way you cluster basic objects into containers affects the concurrency and performance characteristics of your application and the storage characteristics of your federated database. Objectivity for Java provides the ability to trade off concurrency versus space utilization and runtime performance.
The way basic objects are deleted is determined by the type of container, garbage-collectible or non-garbage-collectible, in which the objects are stored.
In a garbage-collectible container, objects are deleted when they are no longer referenced by another object. Such containers are intended to store objects that are related to one another through references or relationships. Just as memory can contain objects that are no longer referenced, a garbage-collectible container can include invalid objects that were left over after some object references were deleted. Objectivity/DB provides a garbage collector that locates and deletes unreferenced objects in this kind of container. However, unlike the garbage collectors available for program execution environments, the Objectivity/DB garbage collector is run under the control of the database administrator.
In a non-garbage-collectible container, invalid objects must be explicitly tracked and deleted by an application. Such containers are primarily designed for use by an application that must interoperate with an application written in a non-garbage-collected language, such as C++. They could also be used to store objects that are not necessarily connected to one another by references. For example, you might create a non-garbage-collectible container to store all objects of a particular class. The default container of a database is non-garbage-collectible to provide interoperability with C++.
When an object becomes persistent, Objectivity/DB automatically assigns it a unique object identifier (OID). An OID is 64 bits in length and is composed of four 16-bit fields identifying the database (D), container (C), logical page number (P), and logical slot number (S) of the object. The string representation of an OID has the form D-C-P-S. Objectivity/DB uses OIDs instead of memory addresses to identify objects, because OIDS provide:
Although storage objects do not have OIDs, database and container identifiers can be cast in the same form as an OID and can be used to reference databases and containers. A database's OID is D-0-0-0; the OID for a container is D-C-P-1.
A persistent object's OID can change during the lifetime of the object only if the object is moved to a new container. When a persistent object is moved or deleted, its OID may be reused for a new persistent object. Application developers do not need to manage or access OIDs. OIDs are reported in some exceptions to identify particular objects.
Naming a persistent object helps you retrieve the object from the database by enabling you to look it up by name. It is also one way of making a transient object persistent.
Objectivity/DB provides several mechanisms to allow you to name persistent objects. You can:
You can retrieve a preexisting persistent object using any of a variety of mechanisms:
Many of the retrieval methods allow you to filter for those objects that:
Searching for objects that meet the conditions in a predicate is an expensive operation when the number of objects being searched is very large. To optimize such searches, Objectivity/DB supports the definition of indexes, which sort persistent objects according to the values in one or more of their fields.
Objectivity/DB indexes have the following characteristics:
Before you can access a retrieved persistent object, you must lock it and fetch its data. In contrast to storage objects, which in most cases are locked automatically by Objectivity/DB, persistent objects must always be locked by your application. Typically this happens when you fetch the object's persistent data. You can also reserve access to the object by explicitly requesting a lock on the object before you fetch its data.
Whenever a basic object is locked, the container in which it is stored is locked. As a consequence, the rules for concurrent access of basic objects are the same as the rules for containers.
At some point during the lifetime of your Objectivity for Java application, you may need to modify your class definitions and consequently, the underlying schema. Once you deploy a federated database, its schema, and database applications to your end users, it will not be practical for your end users to delete their federated databases and re-create them if the schema changes. A database must provide mechanisms to:
These two processes are known as schema evolution and object conversion, respectively.
Schema evolution is required if you make a change to an application-defined persistence-capable class contained in the schema of a federated database. The changes can include:
Objectivity for Java migrates a schema implicitly when objects with a modified definition are made persistent or when an Objectivity/DB object is fetched, and Objectivity for Java detects that the Java class definition does not match the schema. You can also explicitly trigger schema migration through methods in the programming interface.
When you change a schema, existing objects in a federated database that are based on the changed classes may need to be converted to reflect the schema changes. These objects are called affected objects.
Objectivity for Java will implicitly perform object conversion on affected objects when they are accessed. You can also explicitly convert all affected objects in a particular storage object.
This section gives an overview of the main classes in the Objectivity for Java programming interface. The classes are introduced in the order they would be used in implementing a simple application. The role of each class is explained and examples illustrate how to use the classes. A complete application combines all the examples.
The Objectivity for Java API provides some classes that directly map to Objectivity/DB features. These include ooFDObj, ooDBObj, ooContObj, ooObj, whose instances are local representations of Objectivity/DB objects. The API also includes classes, notably Connection and Session, whose instances represent facets of the interaction between an application and Objectivity/DB. Together these two groups of classes provide a rich and flexible interface for developing applications that take advantage of the capabilities of Objectivity/DB and the Java programming language.
The relationships between instances of the classes in an application are illustrated in the following figure.
The following sections give a brief introduction to the classes shown in the previous figure. The classes are introduced in the order they would be used in implementing a simple application. The sections explain, and illustrate with examples, how to use the classes. A complete application that combines all the examples is described at the end of this chapter.
Objectivity for Java comprises four packages:
Your Objectivity for Java application must either import these packages or whatever classes and interfaces are used by your application.
All the constants used by Objectivity for Java general application classes are defined in the oo interface. You can implement this interface in any of your classes; doing so allows you to refer to the constants with their unqualified names, such as READ. If your class does not implement this interface, it must use fully-qualified constant names, such as oo.READ.
An Objectivity for Java application must first establish a connection with the federated database it wishes to work with. It does this by calling the Connection.open static method to obtain an instance of the Connection class.
ExampleThis code fragment opens a connection to a federated database called Vrc for read/write access. The Connection.open method throws two checked exceptions, which the application must catch.
Connection connection; try { connection = Connection.open("Vrc", oo.openReadWrite); } catch (DatabaseNotFoundException exception) { System.out.println("Federated database \"Vrc\" not found."); return; } catch (DatabaseOpenException exception) { System.out.println("Federated database \"Vrc\" not open."); return; }
A session is an extended interaction between an application and a connected federated database. You must create a session before you perform any operations that affect the objects maintained by the connected federated database. A session is an instance of the Session class and is created using the new operator.
Sessions own the local representations of all Objectivity/DB objects accessed by an application. Objectivity for Java does not allow objects that belong to one session to interact with objects that belong to a different session. Sessions also provide the transaction services--begin, commit, checkpoint, and abort--that guarantee consistency between the local representations of Objectivity/DB objects and the objects in a federated database. All persistent operations on Objectivity/DB objects must be performed within a transaction.
ExampleThis code fragment creates a session, begins a transaction, processes Objectivity/DB objects, and commits the transaction.
Session session = new Session(); session.begin(); // Begin a transaction ... // Perform processing on Objectivity/DB objects session.commit(); // Commit a transaction
A federated database is represented by an instance of the ooFDObj class. Each session automatically creates such a representation, which you obtain by calling the session's getFD method.
Databases are represented by instances of the ooDBObj class. There are no public constructors for this class. You create a new database using one of the newDB methods and retrieve an existing database using the lookupDB method of an instance of ooFDObj.
ExampleThis code fragment creates a session and retrieves its associated federated database. It then calls the federated database's hasDB method to check whether a database named VehiclesDB exists and, if so, retrieves it from the federated database. You should check whether the database exists before doing the lookup, because the lookup operation will throw an exception if a database with the name VehiclesDB does not exist in the federated database. If the database does not exist, the example creates a new database in the federated database.
ooFDObj vrcFD; ooDBObj vehiclesDB; Session session = new Session(); vrcFD = session.getFD(); session.begin(); if (vrcFD.hasDB("VehiclesDB")) vehiclesDB = vrcFD.lookupDB("VehiclesDB"); else { vehiclesDB = vrcFD.newDB("VehiclesDB"); System.out.println("Created database \"VehiclesDB\"."); } session.commit();
Objectivity for Java has two container classes: ooGCContObj and ooContObj. Instances of these classes represent, respectively, garbage-collectible containers and non-garbage-collectible containers. Both of these classes may be subclassed to provide application-defined behavior.
Containers are created using the Java new operator, and are initially transient. You can make a container persistent by adding it to a database with the addContainer method. This method requires you to explicitly specify a name for the container (null if the container is to be unnamed), whether the container is hashed, its initial size, and how much it should grow when it needs to accommodate more basic objects. You must make a container persistent before you call any methods of ooContObj. When you make a container persistent, the container is automatically locked for write by Objectivity/DB.
Once you add a container to a database, you can later retrieve it by name with the database's lookupContainer method. When you retrieve a container, it is returned unlocked; when you call the container's system-defined methods, however, Objectivity/DB will automatically lock it for you.
ExampleThis code fragment calls a database's hasContainer method to check whether a container named VehiclesContainer exists in the database, and, if so, retrieves it from the database. If the container does not exist, the example creates a new container in the database.
... // Get session and database ooContObj vehiclesContainer; session.begin(); if (vehiclesDB.hasContainer("VehiclesContainer")) vehiclesContainer = vehiclesDB.lookupContainer("VehiclesContainer"); else { vehiclesContainer = new ooContObj(); vehiclesDB.addContainer(vehiclesContainer, "VehiclesContainer", 0, 5, 10); System.out.println("Created container \"VehiclesContainer\"."); } session.commit();
All persistence-capable classes must be derived from the Objectivity for Java class ooObj or implement interface com.objy.iapp.Persistent.
ExampleThis example illustrates the definition of a persistence-capable Vehicle class. The field types for this example include persistent fields of the Java String class, primitive types, a reference to a persistence-capable Fleet class, and a transient field that contains the daily rate for renting the vehicle.
public class Vehicle extends ooObj { // Persistent fields protected String license; protected String type; protected int doors; protected int transmission; protected boolean available; protected Fleet fleet; // Legal values for transmission field public static final int MANUAL = 0; public static final int AUTOMATIC = 1; // Transient field protected transient int dailyRate; public Vehicle(String license, String type, int doors, int transmission, int rate) { this.license = license; this.type = type; this.doors = doors; this.transmission = transmission; this.available = true; this.dailyRate = rate; } ... // Method definitions }
Persistent basic objects are created using the Java new operator and are initially transient. A basic object becomes persistent when it is stored or clustered into a persistent container. This can occur implicitly when you create an association between the transient object and a persistent object or name the transient object in the context of an Objectivity/DB object, or you can explicitly request that it be clustered into a specific container with the cluster method of any persistent object or database. Most methods defined on ooObj can be called only after the transient object has been made persistent.
ExampleThis code fragment creates a Vehicle object and explicitly clusters it in the container vehiclesContainer.
... // Get session and container session.begin(); // Create transient Vehicle object Vehicle vehicle = new Vehicle("ca1234", "H", 4, Vehicle.STANDARD, 40); // Make vehicle persistent by clustering it in a container vehiclesContainer.cluster(vehicle); // Make vehicle visible to other sessions session.commit();
Before you can read the persistent fields of a retrieved object, the object must be locked and its data must be fetched. The fetch method obtains a read lock on the object and its container before fetching the object's data from the database.
To ensure that your persistent objects are always in the correct state when they are read, you should define access methods to get the value of every persistent field. Each method should call the object's fetch method before returning the field's value. After the first call to fetch, subsequent calls of the fetch method within a transaction do not incur any overhead.
Similarly, the persistent fields of an object should be modified only if the application has a write lock on the object. Also, once the object is modified, it must be marked as such or the changes will not be written to the database when the session commits. The markModified method performs both operations. To ensure that persistent objects are modified correctly, you should define access methods for all operations that set the value of a persistent field. These methods should call the object's markModified method before changing the field.
ExampleThis example illustrates how to define access methods that safely fetch and modify the persistent fields of a Vehicle object.
public class Vehicle extends ooObj { ... // Variable declarations and constructor definition public String getLicense() { fetch(); return this.license; } ... // Get methods for rest of fields public String toString() { fetch(); StringBuffer buffer = new StringBuffer(); if (this.available) buffer.append("AVAILABLE "); else buffer.append("RENTED "); buffer.append("License:" + this.license); buffer.append("Class:" + this.type); buffer.append("Doors:" + this.doors); if (this.transmission == MANUAL) buffer.append("MANUAL"); else buffer.append("AUTOMATIC"); buffer.append(" Rate:" + dailyRate); String strng = new String(buffer); return strng; } public void rentVehicle() { markModified(); this.available = false; } ... // Set methods for rest of fields public boolean isAvailable() { fetch(); return this.available; } }
Objectivity/DB provides a variety of mechanisms for retrieving objects from a federated database. Objects can be retrieved by looking them up by name, traversing object references or relationships, or by scanning storage objects or relationships.
The scan method supports searching for objects based on the value of one or more persistent fields.
ExampleThis example constructs a predicate over one or more of the persistent fields of the vehicle. It then initializes an iterator to return all the vehicles that satisfy the predicate and prints a string representation of all the matching vehicles.
// VehiclesContainer initialized elsewhere ooContObj vehiclesContainer; public void listVehicles(String license, String type, int doors, int transmission, boolean available) { String predicate = new String("license == \"\"" + license + "\" && " + "type == \"\"" + type + "\" && " + "doors >= " + doors + " && " + "transmission == " + transmission + " && " + "available == 1"); Iterator itr; Vehicle vehicle; session.begin(); itr = vehiclesContainer.scan("Vehicle", predicate); // Check whether iterator has found any matching vehicles if (!itr.hasNext()) { System.out.println("Vehicle satisfying predicate: " + predicate + " not found."); session.abort(); return; } // Retrieve each element from iterator while(itr.hasNext()) { vehicle = (Vehicle)itr.next(); System.out.println(vehicle.toString()); } session.commit(); }
To improve the performance of scans performed over specific persistent fields, you can define indexes using a container's addIndex or addUniqueIndex methods.
ExampleThis example defines a unique index that sorts the objects in the container vehiclesContainer according to the values in the vehicle's license field. Before adding the index to the container, the example checks whether an index named VehiclesIndex exists in the container, because the addUniqueIndex method will throw an exception if the container already has an index named VehiclesIndex.
session.begin(); if (!vehiclesContainer.hasIndex("VehiclesIndex")) vehiclesContainer.addUniqueIndex("VehiclesIndex", "Vehicle", "license"); session.commit();
When you have finished interacting with the connected federated database, you should call the close method of the connection object. Applications typically close a connection only once, immediately before exiting. However, you may reopen the connection by calling the reopen method.
The example described in this section combines all the code fragments in this chapter into a complete application. The example application is intended to be used by the agents and managers of a vehicle rental company. The operations supported are:
The application is implemented by four classes:
To execute this example, you need to:
See the Objectivity/DB administration book for information on the tools used to create a federated database and start a lockserver.
When you execute VrcInit, the output will be:
Created database "VehiclesDB". Created container "VehiclesContainer". Added vehicle: License:CA1234 Class:G Doors:4 MANUAL Rate:40 Added vehicle: License:CA7654 Class:H Doors:4 AUTOMATIC Rate:40
Then you can execute Vrc. At the Vrc command prompt you can try the following operations (user input is in boldface):
Enter request (add, list, rent, return, quit) list Do you want to enter a search field? no Searching for ALL vehicles. AVAILABLE License:CA1234 Class:G Doors:4 MANUAL Rate:40 AVAILABLE License:CA7654 Class:H Doors:4 AUTOMATIC Rate:40
Enter request (add, list, rent, return, quit). rent Enter license. ca7654 Looking for vehicle with license: CA7654 Rented: License:CA7654 Class:H Doors:4 AUTOMATIC Rate:40
Enter request (add, list, rent, return, quit) list Do you want to enter a search field? yes Enter field to search (license, class, doors, transmission, or available) available What value of AVAILABLE do you want to search for? true Do you want to enter another search field? no Searching for vehicles with available = TRUE AVAILABLE License:CA1234 Class:G Doors:4 MANUAL Rate:40
An ODMG application interacts with a federated database through instances of the Objectivity for Java Database and Transaction classes. An ODMG application uses a database object to maintain a connection to the federated database and to provide naming of root objects; it uses a transaction object to provide transaction services.
Although database and transaction objects are sufficient for writing an ODMG application, certain Objectivity/DB policies and properties are still maintained by Objectivity for Java connection and session objects, and a session is still responsible for all the local representations of Objectivity/DB objects. Thus, when you open an ODMG database and create an ODMG transaction, corresponding Objectivity for Java connection and session objects are created automatically. Default values for connection and session properties are used, with the following implications for application behavior:
If these constraints and default policies are not appropriate for your application, Objectivity for Java allows you to retrieve the connection and session from their database and transaction, and change the policies and properties. See Chapter 3, "ODMG Application Objects" for further information.
Guide  Reference  Contents  Previous  Next  Index