There are very few restrictions placed on persistent classes. Still, it never hurts to familiarize yourself with exactly what JDO does and does not support.
The JDO specification requires that all persistence-capable classes must have a no-arg constructor. This constructor may be private. Because the compiler automatically creates a default no-arg constructor when no other constructor is defined, only classes that define constructors must also include a no-arg constructor.
| ![[Note]](img/note.gif) | Note | 
|---|---|
| Kodo's enhancer will automatically add a protected no-arg constructor to your class when required. Therefore, this restriction does not apply under Kodo. | 
JDO fully supports inheritance in persistent classes. It allows persistent classes to inherit from non-persistent classes, persistent classes to inherit from other persistent classes, and non-persistent classes to inherit from persistent classes. It is even possible to form inheritance hierarchies in which persistence skips generations. There are, however, a few important limitations:
					Persistent classes cannot inherit from certain
					natively-implemented system classes such as
					java.net.Socket and 
					java.lang.Thread.
					
If a persistent class inherits from a non-persistent class, the fields of the non-persistent superclass cannot be persisted.
All classes in an inheritance tree must use the same JDO identity type. If they use application identity, they must either use the same identity class, or else they must each declare that they use separate identity classes whose inheritance hierarchy exactly mirrors the inheritance hierarchy of the persistent class hierarchy. We cover JDO identity in Section 4.5, “JDO Identity”.
JDO manages the state of all persistent fields. Before you access a field, the JDO runtime makes sure that it has been loaded from the datastore. When you set a field, the runtime records that it has changed so that the new value will be persisted. This allows you to treat the field in exactly the same way you treat any other field - another aspect of JDO's transparent persistence.
JDO does not support static or final fields. It does, however, include built-in support for most common field types. These types can be roughly divided into three categories: immutable types, mutable types, and relations.
Immutable types, once created, cannot be changed. The only way to alter a persistent field of an immutable type is to assign a new value to the field. JDO supports the following immutable types:
					All primitives (int, float, byte,
					etc)
					
					All primitive wrappers (java.lang.Integer,
					java.lang.Float, java.lang.Byte, etc)
					
java.lang.String
java.math.BigInteger
java.math.BigDecimal
java.lang.Number
java.util.Locale
Persistent fields of mutable types can be altered without assigning the field a new value. Mutable types can be modified directly through their own methods. The JDO specification requires that implementations support the following mutable field types:
java.util.Date
java.util.Collection
java.util.HashSet
java.util.Map
java.util.HashMap
java.util.Hashtable
Collection and map types may be parameterized.
			Most implementations do not allow you to persist nested mutable 
			types, such as Collections of 
			Maps.
			
| ![[Note]](img/note.gif) | Note | 
|---|---|
| 
				Kodo supports all JDK 1.2  | 
			Most JDO implementations support mutable fields by transparently
			replacing the field value with an instance of a special 
			subclass of the field's declared type.  For example, if
			your persistent object has a field containing a 
			java.util.Date, the JDO implementation
			will transparently replace the value of that field at runtime
			with some vendor-specific Date subclass 
			-- call it JDODate.  The job of this
			subclass is to track modifications to the field.  Thus the
			JDODate class will override all
			mutator methods of Date to notify the JDO
			implementation that the field's value has been changed.  The
			JDO implementation then knows to write the field's new value
			to the datastore at the next opportunity. 
			
			
			
			
			
			
			Of course, when you develop and use persistent classes, 
			this is all transparent.  You continue
			to use the standard methods of mutable fields as you
			normally would.  It is important to know how support
			for mutable fields is implemented, however, in order to 
			understand why JDO has such trouble with arrays.  JDO
			allows you to use persistent array fields, and it automatically
			detects when these fields are assigned a new array value or set
			to null.  Because arrays cannot be 
			subclassed, however, JDO cannot detect when new values are 
			written to array indexes.  If you set an index of a persistent 
			array, you must either reset the array field, or explicitly tell 
			the JDO implementation you have changed it; this is 
			referred to as dirtying the field.  Dirtying 
			is accomplished through the 
			JDOHelper's
			makeDirty method.
			
Example 4.2. Accessing Mutable Persistent Fields
/**
 * Example demonstrating the use of mutable persistent fields in JDO.
 * Assume Person is a persistent class.
 */
public void addChild (Person parent, Person child)
{
    // can modify most mutable types directly; JDO tracks
    // the modifications for you
    Date lastUp = parent.getLastUpdated ();
    lastUp.setTime (System.currentTimeMillis ());
    Collection children = parent.getChildren ();
    children.add (child);
    child.setParent (parent);
    // arrays need explicit dirtying if they are modified,
    // but not if the field is reset
    parent.setObjectArray (new Object[0]);
    child.getObjectArray ()[0] = parent;
    JDOHelper.makeDirty (child, "objectArray");
    // or: child.setObjectArray (child.getObjectArray ());
}
As the parent-child example above illustrates, JDO supports relations between persistent objects in addition to the standard Java types covered so far. All JDO implementations should allow user-defined persistent classes as well as collections and maps of user-defined persistent classes as persistent field types. The exact collection and map types you can use to hold persistent relations will depend on which mutable field types the implementation supports.
			
			
			
			
			Most JDO implementations also have some support for fields 
			whose concrete class is not known.  Fields declared as type
			java.lang.Object or as a user-defined
			interface type fall into this category.  Because these fields are
			so general, though, there may be limitations
			placed on them.  For example, they may be impossible to query,
			and loading and/or storing them may be inefficient.
			
| ![[Note]](img/note.gif) | Note | 
|---|---|
| Kodo supports user-defined persistent objects as elements of any of the supported collection types. It also supports user-defined persistent objects as keys, values, or both in any supported map type. 
				Kodo supports persistent 
				 | 
This section detailed all of the restrictions JDO places on persistent classes. While it may seem like we presented a lot of information, you will seldom find yourself hindered by these restrictions in practice. Additionally, there are often ways of using JDO's other features to circumvent any limitations you run into. The next section explores a powerful JDO feature that is particularly useful for this purpose.
|    |