com.odi
Interface IPersistent

All Known Implementing Classes:
OSAbstractSet, OSDictionary, OSHashBag, OSHashSet, OSSmallMap, OSTreeMap, OSTreeSet, OSVector, Persistent

public interface IPersistent

Every persistence-capable class must implement the IPersistent interface or be a subclass of a class that implements it.

When you run the class file postprocessor (osjcfp), the postprocessor annotates the appropriate class (the top-level class in your hierarchy) to ensure that IPersistent is implemented. You do not need to put anything special in the class definition for the class to be persistence capable. You just need to run the postprocessor on the class.

Information for running the postprocessor is in the PSE/PSE Pro Java API User Guide, Chapter 8, Generating Persistence-Capable Classes Automatically. If you run the postprocessor, which is the typical way to use PSE/PSE Pro, the rest of the information provided here is background information.

In unusual circumstances, you might choose to completely or partially manually annotate a class so that it is persistence-capable. If you do this, the requirements for implementing the IPersistent interface are described here. Additional information is in the PSE/PSE Pro Java API User Guide, Chapter 9, Generating Persistence-Capable Classes Manually.

Some Java-supplied classes are persistence-capable. Others are not and cannot be made persistence-capable, while others can be made persistence-capable, but there are important issues to consider when you do so.

In previous releases, the com.odi.Persistent class implemented IPersistent and the class file postprocessor (osjcfp) ensured that a class extended the Persistent class. Now, the postprocessor ensures that a class implements com.odi.IPersistent without using com.odi.Persistent. The Persistent class is deprecated and will be removed in a future release.

The IPersistent interface provides two kinds of methods.

The first group of methods handles the creation of the persistent object and the initialization of the contents of the persistent object. These are the xxxxContents() methods.

The second group of methods allows PSE/PSE Pro to retrieve and modify two fields in your class definition. If you run the postprocessor, it adds these fields to your definition. If you do not run the postprocessor, you must insert the following code in your class definition:


 transient private com.odi.imp.ObjectReference ODIRef;

 transient public byte ODIObjectState;

The two fields are the ODIRef field, which stores a reference, and the ODIObjectState field, which holds some object state bits. The underlying runtime classes in PSE/PSE Pro access these fields through the IPersistent accessor methods as needed.

If you define a clone() method in your class, you must ensure that it correctly initializes and checks these fields when it performs a clone operation. Typically, for new cloned objects, your application should initialize ODIRef to null and ODIObjectState to zero.

The IPersistent interface supplies accessor methods (get and set) so that the classes in the com.odi.imp package can use the ODIRef and ODIObjectState fields in a generic way without class-specific knowledge.

If you do not run the postprocessor, you must add the following code to your class definition. If you run the postprocessor, it adds this code for you.


 public com.odi.imp.ObjectReference ODIgetRef() {
    return ODIRef;
 }

 public void ODIsetRef(com.odi.imp.ObjectReference objRef) {
    ODIRef = objRef;
 }

 public byte ODIgetState() {
    return ODIObjectState;

 
  }
    
 public void ODIsetState(byte state) {
    ODIObjectState = state;
 }
  
As with any interface, every method defined in the IPersistent interface must be defined in your class definition. There are several ways you can accomplish this.

If you provide a hashCode() method in your class definition, and you run the postprocessor, the postprocessor does not add a hashCode() to your class definition.

If you do not provide a hashCode() method and you run the postprocessor, the postprocessor always adds one and also adds the ODITheHashCode field to your class definition. The type of this field is int.

If you do not add a hashCode() method and you do not run the postprocessor and your application never calls the hashCode() method on the persistence-capable class, there is no problem. However, if you do not add a hashCode() method and you do not run the postprocessor and your application does call the hashCode() method on the persistence-capable class, the hashcode value will be different across different invocations of the Java VM.

In previous releases, the HashPersistent class was the superclass for classes that needed a hashCode() method based on identity. The HashPersistent class is deprecated and will be removed in a future release.


Method Summary
 void clearContents()
          Resets the values of the fields of an active persistent object to the default initial values of that class of object.
 void flushContents(GenericObject genObj)
          Stores the values of the fields of an active persistent object in an instance of the GenericObject.
 void initializeContents(GenericObject genObj)
          Initializes the values of the fields of a hollow persistent object from data contained in an instance of GenericObject.
 com.odi.imp.ObjectReference ODIgetRef()
          Returns the value of the ODIRef field.
 byte ODIgetState()
          Returns the value of the ODIObjectState field.
 void ODIsetRef(com.odi.imp.ObjectReference objRef)
          Updates the value of the ODIRef field.
 void ODIsetState(byte state)
          Updates the value of the ODIObjectState field.
 

Method Detail

initializeContents

public void initializeContents(GenericObject genObj)
Initializes the values of the fields of a hollow persistent object from data contained in an instance of GenericObject. In other words, hollow objects become active objects with an internal clean state. PSE/PSE Pro calls this method when an application calls ObjectStore.fetch() or ObjectStore.dirty() on a persistent object. Note that the postprocessor inserts these fetch() and dirty() calls where required.

If you are annotating a class manually, any implementation of this method must initialize all fields in the hollow persistent object, including any fields defined by superclasses. Initialize superclass fields by invoking initializeContents() on the superclass. This is similar to calls to superclass constructors, although in this case the superclass initialization is not enforced by the compiler.

A persistence-capable Java class can define a field that does not appear in the list of fields returned by the ClassInfo.getFields() method. Such a field is a transient-only field. The initializeContents() method that is associated with the class must initialize transient-only fields.

If you do not define this method, you can run the postprocessor to add a definition of this method for you.

Parameters:
genObj - The representation of the persistent object that the method should read the field values from.


clearContents

public void clearContents()
Resets the values of the fields of an active persistent object to the default initial values of that class of object. This causes the clean active object to become a hollow persistent object.

If you are annotating a class manually, any implementation of this method must clear all fields in the persistent object, including any fields defined by superclasses. Clear superclass fields by invoking clearContents() on the superclass.

If you do not define this method, you can run the postprocessor to add a definition of this method for you.

See Also:
ClassInfo.create()

flushContents

public void flushContents(GenericObject genObj)
Stores the values of the fields of an active persistent object in an instance of the GenericObject.

The flushContents() method can be called on an object that is in a clean or dirty state. If the object is in a dirty state, flushContents() converts the object to a clean state.

If the object is in a clean state, the object remains in a clean state. PSE/PSE Pro calls flushContents() when a modified persistent object is evicted and when a transaction is committed.

If you are implementing flushContents() because you are annotating a class manually, you must flush all of the fields defined for this class and its superclasses. You flush superclass fields by invoking flushContents() on the superclass.

If you do not define this method, you can run the postprocessor to add a definition of this method for you.

Parameters:
genObj - The representation of the persistent object that this method should write the field values into.


ODIgetRef

public com.odi.imp.ObjectReference ODIgetRef()
Returns the value of the ODIRef field.

If you define this method, you must also define the ODIsetRef() method. If you do not define these two methods, you can run the postprocessor to insert them.


ODIsetRef

public void ODIsetRef(com.odi.imp.ObjectReference objRef)
Updates the value of the ODIRef field.

If you define this method, you must also define the ODIgetRef() method. If you do not define these two methods, you can run the postprocessor to insert them.

Parameters:
objRef - The value returned by ODIgetRef().


ODIgetState

public byte ODIgetState()
Returns the value of the ODIObjectState field.

If you define this method, you must also define the ODIsetState() method. If you do not define these two methods, you can run the postprocessor to insert them.


ODIsetState

public void ODIsetState(byte state)
Updates the value of the ODIObjectState field.

If you define this method, you must also define the ODIgetState() method. If you do not define these two methods, you can run the postprocessor to insert them.

Parameters:
state - The value returned by ODIgetState()

.



Copyright 2005 Progress Software Corporation. All rights reserved.