Selective inheritance of object parameters in object-oriented computer environment6704743Abstract An apparatus, program product, and method of managing entities in an object-oriented environment permit the selective inheritance of parameters or fields from parent entities and into child entities responsive to persistent indications of the inheritability of such parameters or fields stored in a non-volatile memory. Further, in many implementations, basing a determination of inheritability on such persistent information permits inheritance to be selectively restricted for a parameter or field without requiring any changes to the database schema for a database that controls access to the parent and child entities. Claims What is claimed is: Description FIELD OF THE INVENTION
TABLE I
Storage Manager Interfaces
Interface Description
LoadObject Get a handle to an existing object
ReleaseObject Release an entity's handle to an object
GetFeature Get a handle to a feature from an object
CreateObject Create a new object
CreateFeature Create a new feature
SetValue Set a value for a feature
DestroyEntity Remove an object/feature from both persistent
and working storage
The LoadObject interface receives as input from a client an identifier for a requested object, and generally initiates the following operations: 1. The storage manager determines whether a working representation of the object is already in working storage by attempting to find an entry in a local map that matches the identifier provided by the client. Each entry in the local map includes an object identifier and a pointer to a wrapper in the working storage that functions as the working representation of the object. 2. Based upon the result of this query, the storage manager either creates a new working representation (if no entry is found) or returns a handle to the existing working representation (if an entry is found). 3. First, for the case of no entry being found, the following actions are performed: A. The storage manager calls the DBMS to obtain a pointer to the object specified by the input identifier. B. The storage manager creates a working representation by instantiating a wrapper, the class definition of which includes, at a minimum, a pointer field containing the pointer returned by the DBMS and a alias count field for storing the number of active aliases to the object. C. The storage manager adds an entry to the local map including the input identifier and a pointer to the wrapper. D. In response to the addition of the alias to the wrapper in the local map, the wrapper increments its alias count. E. The storage manager returns the pointer to the wrapper to the client as the result of the LoadObject operation. F. In response to returning the pointer for the wrapper to the client, the wrapper increments its alias count, indicating that the client now also holds a handle to the object. 4. Second, for the case of a matching entry being found, the following actions are performed: A. The storage manager returns to the client the pointer to the wrapper that is stored in the matching entry as the result of the LoadObject operation. B. In response to returning the pointer for the wrapper to the client, the wrapper increments its alias count, indicating that the client now also holds a handle to the object. The ReleaseObject interface is called in response to a client desiring to release its handle to an object, and generally initiates the following operations: 1. In response to the client releasing its handle, the wrapper automatically decrements its alias count. 2. If the alias count remains above one, no further actions are taken. However, if the alias count falls to one (indicating that the only alias to the wrapper is in the local map for the storage manager), the wrapper notifies the storage manager that the wrapper is no longer in use. 3. Once notified that the wrapper is no longer in use, the storage manager releases its handle to the wrapper by removing the associated entry from the local map. 4. Once the handle is released by the storage manager, the wrapper decrements its alias count to zero, which causes the wrapper to thereafter to destroy itself and free the memory allocated thereto. The GetFeature interface receives as input from a client a requested feature from a target object, and generally initiates the following operations: 1. The wrapper for the target object (referred to here as an owning wrapper) determines whether a working representation of the requested feature has been created, by searching the local map for an entry corresponding to the requested feature. 2. If the working representation has not been created, the following actions occur: A. The wrapper calls the DBMS to obtain a pointer to the requested feature. B. The storage manager creates a working representation by instantiating a wrapper for the feature, the class definition of which includes, at a minimum, a pointer field containing the pointer returned by the DBMS, an alias count field for storing the number of active aliases to the object, and an owner field for storing a pointer to the owning wrapper. C. The feature wrapper stores the pointer to the owning wrapper in its owner field. D. The owning wrapper increments its alias count as a result of the feature wrapper's alias thereto. E. The storage manager adds an entry to the local map including a "key" providing an identifier for (e.g., a pointer to) the persistent representation of the feature and a "value" of (e.g., a pointer to) the feature wrapper. F. In response to the addition of the alias to the feature wrapper in the local map, the wrapper increments its alias count. G. The owning wrapper returns the pointer to the feature wrapper to the client as the result of the GetFeature operation. H. In response to returning the pointer for the feature wrapper to the client, the feature wrapper increments its alias count, indicating that the client now also holds a handle to the feature. 3. If the working representation has already been created, the following actions occur: A. The owning feature returns to the client the pointer to the feature wrapper that is stored in the matching entry as the result of the GetFeature operation. B. In response to returning the pointer for the feature wrapper to the client, the feature wrapper increments its alias count, indicating that the client now also holds a handle to the feature. The CreateObject interface generally initiates the following operations: 1. The storage manager generates a unique identifier for the object. 2. The storage manager calls the DBMS to instantiate an object based on the minimal object entity classification to generate a persistent representation of the object. In response, the DBMS creates the persistent representation of the object according to the database schema, storing the unique identifier supplied by the storage manager. The DBMS then returns a pointer to the newly created object to the storage manager. 3. The storage manager creates a working representation of the object by instantiating a wrapper in working storage, following the general sequence of operations discussed in steps 3B-3F of the LoadObject interface discussed above. As a result of the operation, a pointer to the working representation of the object is returned to the client. The CreateFeature interface generally receives a pointer to an owning entity (object or feature) as well as feature type information, and initiates the following operations: 1. The storage manager calls the DBMS to instantiate a feature based on the minimal feature entity classification corresponding to the requested feature type to generate a persistent representation of the feature. In response, the DBMS creates the persistent representation of the feature according to the database schema, storing in the owner field a pointer to the owning entity supplied by the storage manager. The DBMS then returns a pointer to the newly created feature to the storage manager. 3. The storage manager creates a working representation of the feature by instantiating a feature wrapper in working storage, following the general sequence of operations discussed in steps 2B-2H of the GetFeature interface discussed above. As a result of the operation, a pointer to the working representation of the feature is returned to the client. The SetValue interface generally receives from a client a new value directed to the specific feature to be modified. The storage manager handles such a request by forwarding the request to the DBMS, such that the new value is stored in the persistent representation of the feature. By virtue of the use of a wrapper that points to the persistent representation, but does not actually store any values separate therefrom, modifications to the contents of features are automatically persisted to the persistent representations responsive to such modifications. The DestroyEntity interface permits entities (objects and/or features) to be destroyed in a recursive manner. In response to DestroyEntity request, the following operations are performed: 1. The entity calls the DBMS to get pointers to all features that are aliased by the entity. 2. For each aliased feature, a DestroyEntity request is passed to the aliased feature. 3. Once all aliased features have been destroyed, the entity calls the DBMS to destroy the persistent representation thereof. 4. The entity marks itself as "invalid". In some implementations, the entity could free itself from memory once the persistent representation is destroyed. However, in the illustrated implementation, this is not performed so that a wrapper can remain in memory until all outstanding aliases to it are released. It should be noted that the working representation of a program entity in the illustrated embodiment essentially is an interface to the actual data stored in the persistent representation of the program entity. Modifications to a working representation, which can include modifications to the contents of an entity (e.g., to change the value in a feature) as well as modifications to the structure of an entity (e.g., to add or remove a feature from an object), are therefore simply passed through to the persistent representation. In other implementations, however, it may be desirable to copy all or a portion of the contents of a persistent representation of a program entity into a working representation, and thus perform modifications to the working representation as well. However, by maintaining the actual contents of a program entity in a single representation (i.e., the persistent representation), the overall size occupied by a working representation is minimized. In addition, using known caching facilities provided in an underlying DBMS, the actual data within the persistent representation may be cached in working memory as a matter of course to improve performance. Also, in some implementations it may be desirable to cache some additional information regarding an entity separate from the DBMS, e.g., to cache the ID for an object and/or a value for an attribute, to further improve performance. To further illustrate the above-described functionality, FIGS. 10A-10G illustrate the manipulation of a plurality of program entities in an exemplary programming environment 70, including persistent storage 72 and working storage 74. As shown in FIG. 10A, persistent representations of a pair of exemplary program entities, objects 76 and 78 are shown stored in persistent storage 72. Object 76 owns three feature program entities, a name feature 80, an age feature 82 and a friends feature 84, persistent representations of which are also stored in persistent storage 72. Likewise, a name feature 86 and a friends feature 88 are owned by object 78, persistent representations of which are also stored in persistent storage 72. Objects 76, 78 are related to one another through cross-aliases stored in friend features 84, 88. FIG. 10B illustrates the result of a LoadObject operation performed on object 76. Given no working representation is currently in storage 74, as a result of this operation, a working representation 90 of object 76 is created in working storage 74. Working representation 90 is a wrapper, including an alias to the persistent representation, stored in an implementation ("IMP") field 92. Representation 90 also includes an alias count field 94, storing the number of aliases to the object (here, one alias by virtue of the new attempt to get a handle to the object). It will be appreciated that additional attempts to access the object will not create a new working representation. Instead, the alias count is increased and an alias to the existing working representation is returned. FIG. 10C illustrates the result of a GetFeature operation performed on object 76, to get a handle to the friends feature 84 of object 76. Given no working representation is currently in storage 74, as a result of this operation, a working representation 96 of feature 84 is created in working storage 74. Working representation 96 is a feature wrapper, including an alias to the persistent representation (stored in IMP field 98), an alias count field 100, storing the number of aliases to the feature, and an owner field 102, storing an alias to the wrapper for the owner to the feature (here, working representation 90). As an additional aspect of this operation, the addition of an alias in owner field 102 increments the alias count for object 76. FIG. 10D illustrates the result of a LoadObjectFromFeature operation performed to access the first aliased object stored in feature 84 of object 76. As a result of this operation, a working representation 104 of object 78 is created in working storage 74, including an alias count of one stored in field 106 and an alias to object 78 stored in field 108. It should be noted that, by maintaining separate working and persistent representations of program entities, a potentially infinite object model may be maintained within a finite memory space. As an example, with objects 76, 78, successive calls to retrieve the "friend" of each object could be made ad infinitum. FIG. 10E next illustrates the result of a CreateFeature operation performed to add an "age" feature 110 to object 78. A default value (typically taken from a feature definition associated with the feature), is initially stored in feature 110. However, no working representation of the feature is created in working storage, as no handle to the feature is returned as a result of the operation. FIG. 10F illustrates the result of a GetFeature operation performed on object 78, followed by a SetValue operation performed on the feature for which a handle is obtained. The GetFeature operation results in the creation of a working representation 112 of feature 110, including an alias count of one in field 114, an alias to feature 110 in IMP field 116 and an alias to working representation 104 of object 78 in owner field 118. Once the handle is obtained, the SetValue operation then updates the persistent representation of field 110 to the desired value. FIG. 10G illustrates the result of a release of a handle to feature 110, e.g., as a result of a ReleaseObject operation. Assuming the alias count stored in field 114 of working representation 112 is one prior to the operation, the release results in the working representation 112 being freed from working storage 74. Also, the alias count of the owning object working representation 104 is decremented. Through the use of dynamic memory management in the manner discussed herein, program entities may be automatically persisted in a timely and reliable fashion. Often, application reliability and development speed are improved due to the increased reliability, reduced risk of losing changes, and the reduced need for developer-initiated persist operations. Database Organization Based upon the above-described memory management scheme discussed above, program entities may be populated in database 44, 46 by entity management system 50. The format of such program entities are generally defined in meta model layer 54, with the memory management thereof managed by storage layer 52 in the manner discussed above. FIG. 11 illustrates an exemplary class diagram 130 representing the basic entity classifications used to define at meta model layer 54 all program entities stored in integrated development and runtime environment 42. An entity classification is analogous in many respects to a class in an object-oriented environment. All entities in environment 42 are based on a container entity classification 132, which incorporates at a minimum a plurality of lists 134-142, each of which potentially contains one or more aliases to various types of feature entities that are aliased by a container, and thus serve to "describe" the container. An attribute list 134, for example, provides a list of attributes describing the container. Behavior list 136, reference list 138 and relationship list 140 likewise provide lists of behaviors, references and relationships describing the container. Occurrence list 142 (which is optional), serves a slightly different purpose--that of providing aliases to all references that alias the container, i.e., those references for which the container is a target. This form of "back link" assists in navigation through entities stored in the database. Two types of entity classifications, an object entity classification 144 and a feature entity classification 146, extend the basic container entity classification 132. Object entity classification 144 represents the minimal stand-alone entity--i.e., an entity that is not "owned" by any other entity in the database. Classification 144 adds a unique ID field 148, thereby providing an identifier with which each stand-alone entity in the database can be located. Feature entity classification 146 represents the minimal feature entity, which is required to be "owned" by another entity in the database. As such, classification 146 adds an owner field 150, which provides an alias to the entity (whether an object or feature) that owns the feature entity. As discussed above, ownership of one entity by another entity dictates that the owned entity is automatically terminated (i.e., destroyed or otherwise released from memory) responsive to termination of the entity that owns such owned entity. Feature entities are further defined as being undefined or defined. In the illustrated embodiment, only one undefined feature is supported, represented by a reference entity classification 152. The reference entity classification adds a target field 154, which provides an alias to the target of the reference. Defined features are represented by defined feature entity classification 156, which adds a feature definition field 158 to the feature entity classification. Field 158 includes a pointer to a feature definition entity, which serves to provide a "kind" or "type" for a feature. A feature definition entity, or simply a "definition entity", is based on a feature definition entity classification 160, which extends object entity classification 144 to provide a defined features list 162 that includes pointers to each feature entity defined by the feature definition. Given that a feature definition is a type of object entity, the feature definition is stand-alone, and includes a unique identifier. A benefit of such an arrangement is that certain features may be referenced programmatically through their feature definitions, such that the identity of the owning entity for a particular feature is not required to access the feature. Defined feature entities are further defined as either relationships, behaviors or attributes, represented by relationship entity classification 164, behavior entity classification 166 and attribute entity classification 168. Relationships are principally used to hold a set of aliases to reference entities that reference other entities that are related in some fashion to one another (e.g., friends, To Do items, clients, etc.). Behaviors are principally used to hold one or more actions capable of being performed by an owning entity, typically through a reference or function call to a specific routine, and/or though incorporation of the actual program code for the routine. Attributes are principally used to hold values (e.g., a represented by value field 170 added to the defined feature entity classification by attribute entity classification 168). In some implementations, it may be desirable to permit other entities to store values, particularly other feature entities. Also, in some instances, attribute, behavior, relationship and/or reference features may be based on the same entity classifications, so long as such features remain owned by another entity and capable of owning another entity. However, by enforcement of value storage in attributes, and the maintenance of separate classifications for attributes, behaviors, relationships and references, it is believed that the resulting computer language defined by the entity classifications provides relatively greater intuitiveness, while maintaining comparable expressiveness. To permit each entity in the database to ultimately be capable of being located, the unique identifier for each stand-alone entity (object or feature definition) is maintained in a map or table that couples each unique identifier with a pointer to the entity identified by such identifier. For example, as shown in FIG. 12, it may be desirable to maintain separate object and feature definition maps 180, 182, each including a plurality of entries 190, 192 for respectively storing in an ID column (e.g., column 194 for map 180) the unique identifiers for all of the object and feature definition entities stored in the database (e.g., entities 184, 186, and 188), with aliases to the actual object and feature definition entities mapped to each unique identifier (e.g., as represented by column 196 of map 180). All entities created in environment 42 are based upon one of object entity classification 144, feature definition entity classification 160, reference entity classification 152, relationship entity classification 164, behavior entity classification 166 and attribute entity classification 168, such that each of these classifications form the basic semantic entity classifications for the "computer language" implemented in environment 42. The remaining classifications are simply base classifications that assist in implementing the basic entity classifications in an object-oriented environment such as c++, although no entities are actually instantiated from such intermediate entity classifications. Definition Entities As discussed above, definitions form an important component of the herein-described entity management system, essentially serving as a kind of "template" or even "parent" entity for fields that appear in a database. Every dependent entity, e.g., every defined feature such as an attribute, behavior or relationship, is associated with a feature definition. While conventional relational databases have to an extent recognized the benefit of identifying unique features (e.g., individual columns in a relational database), the herein-described entity management system is unique in that it "objectizes" this concept to make it a fully formed object in its own right. As a further example of the use of definition entities, FIG. 54 illustrates a pair of distinct entities 800, 802, each with its own structure. Each entity 800, 802 has an address field 804, 806, but that field appears in a different physical location in each entity. By associating fields 804, 806 with a definition entity 808 (which has a unique identity, permitting the definition to be referred to and retrieved via a unique ID 810), it is possible for the system to support logical operations like "Find all entities whose Address Field contains `Cincinnati`", even in situations where the list of entities being searched is heterogenous and some or all of the entities were defined by the end user. Another important aspect of a definition entity is its existence as a separate entity in the system. A definition can also contain fields, can define default values for all newly created fields based on it, and can define a complex structure that can be shared by all of its defined fields. This makes it possible for a system to support constraints on fields (e.g., to limit the value of a field to a certain range, limit the contents of a relationship to only entities of a certain type, etc.). FIG. 55, for example, shows a locate field routine 820 that shows the logic used when the entity management system looks for a particular field on an entity (here the aforementioned "address" field). Because the system is dynamic and flexible, the position of a field inside an entity may not be known, so the system must locate it by the unique ID of its associated definition. Routine 820 begins in block 822 by getting the unique ID of the definition (here, the address definition) that describes the field to be located. Next, block 824 initiates a FOR loop to process each field in the entity. For each such field, block 826 attempts to determine if the unique ID of the field's definition matches that of the definition being searched. If so, control passes to block 828 to return the located field and terminate the routine. If not, however, control passes to block 830 to get the next field in the entity, and then to block 826 to analyze the next field. If all fields are processed without a match, block 830 passes control to block 832 to return a NULL value and terminate the routine. FIG. 56 illustrates a create field routine 840 showing the logic used when creating a new field (e.g., an attribute or relationship). Routine 840 begins in block 842 by adding the field to the entity, using logic described elsewhere herein. In addition, as shown by block 844, a field is required to be associated with a definition in order to exist in the system, and this association is established at the moment when the field is added to an entity, and prior to completion of routine 840. If no definition is supplied, a default definition may be used. Moreover, in general, duplicate fields are not allowed. Using the basic building blocks of the herein-described object organization (definitions, attributes, and relationships), higher-level capabilities may be overlayed onto the basic database organization, such as object inheritance; selective inheritance; bi-directional relationships; containment relationships (i.e., so that when an owning entity is destroyed, all entities in the containment relationship are also destroyed, and when an owning entity is copied, all entities in the containment relationship are also copied); type constraints (i.e., so that an entity or relationship can only contain other entities of a particular type, e.g., with a specified parent, grandparent, etc.); cardinality constraints (i.e., so that an entity or relationship can contain at most X entities, and/or cannot contain less than Y entities); create-in associations (i.e., so that whenever a new child of an entity is created, the child is automatically added to one or more target locations, e.g., a new Company instance will always be added to an "All Companies" folder); constrained and multi-value attributes (i.e., to support radio buttons or drop-down list boxes where an attribute must hold a value from a pre-defined set of values or an attribute can hold multiple values from a pre-defined set of values. As an example of the latter attributes, consider a font selection dialog, which may include drop-down lists for font size, font face, etc. Such a control might be supported through multi-value attributes that have two relationships on them: one relationship that holds a list of "allowed choice" objects; and another relationship that holds a list of the "current choice" objects. As another example, FIG. 57 shows an example of how the herein-described object organization can be used to support "type constraints"--that is, to restrict the type of entity that can be referenced from another entity. In this example, a "contacts" entity 900 is "constrained" to hold only "person" entities by virtue of a "constraining types" relationship definition entity 902. Any time an entity has a relationship of this type attached to it, and that relationship is not empty, the entity management system uses the entities in that relationship as an "allowed set" and limits what can be added to the owning entity. FIG. 58 illustrates an exemplary add item routine 910 that shows the logic used to enforce type constraints, here to add a destination entity to a relationship. It is to be noted that this functionality is not directly implemented within the herein-described object organization, this functionality is implemented at a relatively higher layer in the entity management system (in particular, the meta model layer), and shows how the flexibility of the underlying generic organization or schema permits various widely used, and useful, higher-level capabilities, to be implemented. Routine 910 begins in block 912 by determining whether the destination for the defined relationship has a constraining type defined by the relationship definition for that relationship. If not, control passes to block 914, where the item is added as a destination for that relationship, and routine 910 terminates. If, however, a constraining type is defined, block 912 passes control to block 916 to get all items from the constraining type definition. Block 918 then determines whether the item being added is a child of one or more of the constraining types in the definition. If so, control passes to block 914 to add the item. If not, however, an "invalid type" indication is returned and routine 910 terminates without adding the item. FIG. 59 shows another example of a higher-level functionality, this time of a "choice attribute," which is an attribute that takes its value from a set of pre-defined allowed choices. In this implementation, a choice attribute entity 930 has two relationships 932, 934 attached to it. The items held by the first relationship 932 define the set of allowed choices or values for the attribute. The item (or items) held by the second relationship 934 define the current selected choices or values for the attribute. In this example, the attribute is a font face, with the first and second relationships associating the font face with a number of possible font face values. FIG. 60 illustrates a get attribute value routine 940 that shows the logic that may be used to retrieve the value of an attribute. Routine 940 begins in block 942 by determining whether the attribute is a choice attribute or not. If not, control passes to block 948 to retrieve the value "normally" by looking directly in the attribute. But if it is, control passes to block 944 to retrieve all of the items in the current choice relationship on the attribute, and then to block 946 to return the value fields from those items as the value of the attribute. It should be noted that an important aspect of the herein-described object organization is the philosophy that "every field is an entity." As an example, in supporting choice attributes, two relationships have been attached to the attribute. Further, these relationships, in turn, could be constrained, e.g., the current choice relationship may have a maximum cardinality of one, indicating a single-choice attribute. Because the maximum cardinality field would be implemented as an attribute, an attribute entity would need to be placed on the relationship. Further, if the maximum cardinality attribute was defined as a choice attribute, then that attribute would need to contain two relationships, one of which would have an attribute which would contain two relationships, and so forth. As such, it may be seen that practically any higher-level functionality of an object-oriented environment may be implemented directly on top of the herein-described object organization. Moreover, given the flexible, dynamic and powerful abilities of the entity management system described herein, such functionalities can often be implemented without requiring any modification to the underlying organization, and in particular without requiring any database schema modification or program code recompilation. Database Seeding Another important aspect of the illustrated entity management system is the concept of database seeding. While some implementations may require no database seeding, and may rely on the aforementioned object classifications, the illustrated embodiment relies on some degree of seeding of basic entities to support a number of the types of unique functionality discussed herein, e.g., object inheritance (including implicit inheritance and selective inheritance), and bidirectional relationships (discussed below), among others. For each of these functionalities, feature definition entities may need to be created and placed in the database, including, for example, a "parent" relationship, a "should inherit" attribute, a "back link" relationship, etc. By supporting such functionalities in populated entities, rather than in the core schema, the core schema is kept as simple and lean as possible. However, in other implementations, such functions may be implemented directly within the core schema itself, rather than in any populated entities. Moreover, other functionalities described herein as being implemented within the core schema may be implemented in higher-level populated entities in some implementations. FIG. 61, for example, shows how database seeding may be relied upon to support dynamic, user-definable object inheritance. The core schema described herein in not configured to include at its most basic level the concept of object inheritance. In the illustrated implementation, this concept is introduced by creating a parent definition entity 850 in the database, used to define the characteristics of a parent relationship 854 between any parent and child entity (e.g., parent entity 856 and child entity 858). This parent definition entity is typically referred to as a system definition, to distinguish it from user-created definitions. Like other system definitions, the unique ID 852 of the parent definition entity 850 is known to entity management system 50, and this definition is used to create and maintain the parent-child relationships between entities. The entity management system defines and uses other key objects and definitions, such as the gene attribute (used for selective inheritance), the name attribute (a very common field used on almost all entities), the backlink relationship (used for bi-directional relationships), and so forth. These other definitions are described in greater detail in other sections of the instant disclosure. Implicit Inheritance Another feature that may be implemented in an entity management system consistent with the invention is that of "implicit" inheritance, whereby inherited fields and field values (or parameters and parameter values) are duplicated in working memory when a child entity is loaded from persistent storage and are not duplicated in the persistent storage itself. Thus, in addition to inheriting all or part of the structure of a parent entity, a child entity can also inherit all or part of the content, or data, stored in the parent entity. Doing so can significantly reduce the amount of duplicate information stored in a database and while still reducing the cost of changing the structure of entities stored in a populated database or distributed collection of databases. In addition, an entity management system consistent with the invention may also support the ability for a child to gain its own copy of an inherited field, e.g., in response to an operation that sets the child's field to a unique value. In this situation, the child is said to "override" the inherited field value. Consistent with this invention, when an inherited but not-owned field is modified, a new field may be added to the database for that child, with the child gaining an "override" for that inherited field. Once a child entity overrides a field, changes to the parent entity's field will have no effect on the child's field. To implement inherited features, generally an ordered traversal through an ownership chain of a child entity is performed in response to a request for a field from a database to determine which entity owns the field. First, the child entity itself is queried to determine if the field is owned by that entity. Otherwise, the ownership chain is traversed until an owning parent entity is found, and a copy of the field in that owning entity is returned as a result of the request as if the field were directly owned by the child entity. As such, the in-memory copy of an inherited field may be considered to be a "virtual" or "implicit" field because it only appears to exist in the persistent storage of the database. To minimize the performance impact of changes to the structure and/or contents of parent entities, whenever a new field is added to a parent entity, or the value of an existing field is changed on a parent entity, child entities that are not in use (e.g., in working memory) are not immediately affected. This is implemented by ensuring that child entities gain inherited fields when they are loaded into working memory. The result is that the time and expense of changing the structure of widely used entities in a fully-populated database may be greatly reduced, since making any change does not require physically traversing to all children, grandchildren, etc. of a parent, nor does it require loading all descendants of the parent into working memory. Furthermore, the amount of redundant data stored in a database may be greatly reduced. Also, by reducing redundant data, the chance of "missing" duplicated data is reduced during an update of a database, which in turn can reduce the number of database errors, incorrect values, or out-of-sync entities. In the illustrated embodiment, implicit inheritance is implemented within the object model layer 56 of entity management system 50 (FIG. 3), although such functionality may be implemented at other layers consistent with the invention. Furthermore, in the illustrated implementation, event notification is utilized to keep child entities that are in the volatile memory synchronized with their parent entities. Event notification is a well-understood mechanism within the art, and a number of conventional designs for event notification components may be used to fulfill this role. For example, in the illustrated embodiment, a publish-subscribe event notification mechanism is utilized, the use and configuration of which is generally understood in the art. In general, implicit inheritance is managed by a software interface in object model layer 56 that creates in-memory representations of fields that are inherited but not over-ridden ("implicit" fields). This interface also automatically detects when such a field is modified, and creates a field on the child entity to hold the overriding information. In addition, when a new field is added to a parent entity, or the value of a parent field is changed, the interface ensures (by sending an "event notification") that all children currently in memory are updated to reflect the change. As shown in FIG. 13, for example, an object model layer load entity routine 200 is called in response to a request to access a particular entity in entity management system 50. In response to such a request, block 202 copies the requested entity into working storage, i.e., creates a working representation of the entity, which typically takes the form of a wrapper that aliases, or points, to the persistent representation of the entity in persistent storage. It is typically through the working representation of the entity that future accesses to the entity are processed. Next, block 204 subscribes the entity (in particular, the working representation thereof) to receive event notifications from all parent entities to the entity. In a single inheritance object model, only one parent entity would exist. In a multiple inheritance object model, however, more than one parent entity may exist. Upon completion of block 204, routine 200 is complete. Typically, a handle to the created working representation of the entity is returned as a result of the routine. FIG. 14 next illustrates a deallocate entity routine 210 that is called whenever an entity needs to be deallocated, e.g., whenever the working representation of the entity is no longer in use. Routine 210 begins in block 212 by releasing the working representation of the entity from working storage. Next, block 214 unsubscribes the entity from event notifications from its parent(s). Routine 210 is then complete. As a result of the subscription and unsubscription of an entity based upon the creation and deletion of a working representation of the entity, it may be seen that only entities that are currently in use (i.e., have existing working representations) will be notified whenever a parent entity sends a notification. Thus, in response to a modification to a parent entity, only those child entities that are currently in use will be immediately updated responsive to such modification. For all other child entities, no updates will occur immediately. Rather, such non-used child entities will be dynamically constructed when they are later used based upon the modified parent entity in existence at that time. FIG. 15 next illustrates a get field routine 220 that is called in response to a request to use a field in a particular entity. In this implementation, the term field is considered to be one example of a parameter that defines some characteristic of a particular entity. In entity management system 50 discussed herein, where fields or parameters for an entity are typically implemented using separate entities that are aliased by that entity, a field may comprise an alias or pointer to another entity. In other implementations, however, a field or parameter may represent a storage location or variable directly implemented within an entity. Routine 220 begins in block 222 by determining whether the entity owns the requested field--that is, whether a persistent representation of the field is associated with (e.g., logically arranged within) the persistent representation of the entity. If so, control passes to block 224 to return a handle to the owned field as the result of the get field request, whereby routine 220 is complete. If not, however, block 222 passes control to block 226 to get the parent entity to the current entity, typically by traversing an alias to the parent entity. Next, block 228 determines whether that parent entity owns the requested field. Put another way, block 228 determines whether the requested field is implicitly inherited from the parent entity. If so, control passes to block 230 to build a working copy or representation of the requested field in the working storage. The working representation of the requested field is accessible via the working representation of the entity upon which the get field request was made, e.g., by being logically arranged within the working representation of such entity, or being otherwise aliased or linked to such working representation. Moreover, the working representation of the requested field is associated with the original, persistent representation of the requested field in the parent entity that owns the requested field, e.g., via an alias to the persistent representation of the parameter in the owning parent entity. Once a working representation of the requested field has been created, a handle to the working representation is returned in block 232, and routine 20 is complete. Returning to block 228, if the current parent entity does not own the requested field, control passes to block 234 to determine whether a grandparent entity (i.e., a parent entity to the current parent entity) exists. If so, control returns to block 226 to get such grandparent entity and determine whether such grandparent entity owns the requested field. As such, the ownership chain of the original entity is traversed sequentially until the owning entity of the requested field has been found. If no such entity is found, block 234 passes control to block 236 to return a "null" handle and terminate routine 220. In applications where multiple inheritance is supported, it should be appreciated that multiple paths may be defined in an ownership chain, such that routine 220 would need to be configured to traverse all such paths to locate the appropriate owning entity. As discussed above, the aforementioned subscription notification mechanism ensures that modifications to a field or parameter in an entity will be propagated to other entities for which working representations thereof exist in the working storage. FIG. 16, for example, illustrates the operation of a modify field routine 240, called in response to a request to modify the contents, e.g., a stored value, associated with a particular field. The modify field request presumes a handle has been obtained for the requested field (e.g., via a get field request), so that a working copy of the requested field exists in the working storage. Routine 240 begins in block 242 by determining whether the entity owns the field, i.e., whether the field is or is not implicitly inherited from another entity--typically by determining if the working copy of the field includes an alias to the persistent representation of the entity. If the entity owns the field, control passes to block 244 to modify the existing field, e.g., by traversing the alias in the working copy of the field to the persistent copy of the field for the entity, and modifying the contents of such persistent copy. Next, block 246 publishes a "field changed" event to the child entities that have subscribed to the current entity. Given that such subscriptions are registered only when a working representation of a child entity has been created, it may therefore be seen that only child entities that are currently in use are immediately notified of the modified field. Routine 240 is then complete. Returning to block 242, if the entity does not own the field, control passes to block 248 to "override" the implicitly inherited field and convert such field to a local, owned field for the entity. Specifically, block 248 creates a new persistent representation of the field in the persistent representation of the entity. In addition, it may be desirable to update the alias in the working representation of the field to alias the new field in the entity. In the alternative, a new working representation of the field may also be created, so that the original field can be maintained in working storage if other entities contain handles to the original field. Next, block 250 modifies the persistent representation of the new field to include the overriding data. Control then passes to block 246 to publish a "field changed" to any subscribed child entities. Routine 240 is then complete. FIG. 17 illustrates a field changed event handling routine 260 that is called in response to receipt of a "field changed" event received by a subscribed entity. Routine 260 begins in block 262 by determining whether the entity receiving the notification owns the specified field--that is, whether the field has been overridden in the local entity. If so, routine 260 terminates. If not, however, the children of the local node are notified of the field change by publishing another "field changed" event to all of the in-use children of the local node, and routine 260 then terminates. As such, it may be seen that the field modification is propagated to all children that implicitly inherit a modified field. However, since retrieving the contents of a field still operate directly on the owning entity of a field, the actual modification to the contents of the field are not actually propagated via the event notification mechanism. FIG. 18 illustrates an add field routine 270, which is called in response to a request to add a field to a particular entity. Routine 270 begins in block 272 by creating the field, i.e., by creating a persistent representation of the field in the persistent representation of the entity. Next, block 274 publishes a "new field" event to the children of the entity, and routine 270 terminates. As will become more apparent below, publication of the "new field" event results in each in-use child entity immediately being updated with a new implicitly inherited field. Specifically, FIG. 19 illustrates a new field event handling routine 280 that is called in response to a "new field" event received by an entity. Routine 280 first begins in block 280 by determining whether the entity owns the field being added--that is, whether the entity has overridden the parent entity with regard to this field. If so, routine 280 terminates. However, if the entity does not own the field, control passes to block 284 to build a working copy of the field in the working storage, with such working copy permitting access to the persistent representation of the field for the owning parent entity. Block 286 then publishes a "new field" event to each of the in-use children of the entity, such that the new field is propagated to all in-use descendants of the entity that added the new field. Routine 280 is then complete. In some implementations, it may also be desirable to permit application code or entities to also receive "new field" or "field changed" events, e.g., so that any views displayed to a user are updated to immediately reflect changes made to entities. It should be noted that typically most child entities will not be in memory when a "new field" or "field changed" event is published. Any children not in working memory (not in-use) are not affected by this operation. However, whenever such unused children are next loaded into memory, if the new field is requested from any such child, the logic of get field routine 220 will be invoked, and an implicit copy of the parent's feature will be returned. Implementing such functionality permits, for example, a parent entity's structure to be changed while an application is running, yet permitting the change to be made efficiently, even though the parent entity may have hundreds, thousands, or even millions of child entities in existence, most of which are not currently "in-use."Nonetheless, the next time any child entity is put into use, it will automatically reflect the new shared structure. In this situation, upgrade utilities may not be needed, nor will an environment need to be shut down and restarted, and the change will typically take effect in seconds, rather than in minutes, hours, or even days as might be required for a very large system. FIGS. 20A-20C illustrate a working example of implicit inheritance. As shown in FIG. 20A, for example, a working storage 300 and a persistent storage 302 are illustrated as including a parent entity ("customer") having a persistent representation 304 with a customer number ("CUSTNUM") field 306 (with a "blank" or null value) and a preferred field 308 with a default value of "no". An exemplary pair of child entities ("customer #223" and "customer #224") with persistent representations 310, 314 are also illustrated, with each including a customer number field 312, 316 that overrides the customer number field 306 of the parent entity. However, given that each child entity does not explicitly override the preferred field 308, each child entity is considered to implicitly inherit this field from the parent entity. It is assumed for the purposes of this example, that in the configuration of FIG. 20A, the "customer #223" child entity has been placed "in-use", and the entity has been loaded into memory, creating a working representation or wrapper 318 in working storage 300. Assume also that a handle to the customer number field for the in-use child entity has been retrieved via a get field request directed to working representation 318. As a result of the operation of get field routine 220 (FIG. 15), a working copy 320 of the customer number field is created within wrapper 318, with an alias included in such working copy so that the value "223" stored in the overriding field 312 would be returned as a result of a "get value" request on the field. It should be appreciated that the inclusion of the specific value in field 320 does not require that the data itself be stored in wrapper 318. As discussed above, for example, an alias to field 312 of persistent representation 310 may be included within field 320, so that an access to field 320 results in retrieval of the requested value directly from field 312. FIG. 20B illustrates the result of a "get field" request for the preferred field directed to the "customer #223" child entity. Via the operation of get field routine 220 (FIG. 15), it would be determined that the "customer #223" child entity does not own the "preferred" field. As such, an alias to the "customer" parent entity would be traversed, and it would be determined that the parent entity owns the "preferred" field. As a result, a working copy 322 of the "preferred" field is created in wrapper 318 (including an alias to field 308 in persistent representation 304), and a handle to field 322 would be returned as a result of the operation. Any subsequent request to access the contents of the field would result in retrieval of the requested value directly from field 308 in persistent representation 304. As such, it should be noted that, for the implicitly inherited "preferred" field, only the working representation 318 of the child entity is modified. The persistent representation 310 typically remains unchanged, and no space is used up in the persistent storage to redundantly store the same "no" value for the "preferred" field. FIG. 20C next illustrates the result of an "add field" request directed to the "customer" parent entity, in particular to add a "location" field to the entity. In response to such a request, add field routine 270 (FIG. 18) would be executed for the parent entity, resulting in the creation of a new location field 324 in persistent representation 304 (a sample value is also shown, although storage of such a value may or may not be performed via a separate "set value" operation). Then, a "new field" event would be published to all in-use children of the parent entity--in this case, the "customer #223" child entity, and a working copy 326 of the field would be created in the wrapper 318 therefor, including an alias to the persistent representation of the field in the persistent copy of the parent entity. It should be noted, however, that for any non-used child entities of the parent (e.g., the "customer #224" child entity), such child entities would not be updated immediately to reflect the new inherited field, since no working copies thereof would exist in working storage 300, and thus no subscriptions would be active for any such child entities. As a consequence, it may be seen that, for example, if a parent entity had thousands of child entities, but only a few of such child entities were in use, the addition of a field to the parent entity would require immediate modifications to only those few child entities that were in use--a substantial savings in terms of efficiency and response over a design where modifications were immediately propagated to all child entities that inherited from a parent entity. Implicit inheritance may find applicability in other environments, e.g., where separate in-memory and persistent representations of entities are not maintained, or in other environments such as relational database environments. Other modifications will be apparent to one of ordinary skill in the art having the benefit of the instant disclosure. Selective Inheritance Another feature that may be implemented in an entity management system consistent with the invention is that of "selective" inheritance, without requiring changes to an underlying database schema. As such, fields or parameters in a parent entity for which it is not desired to be able to inherit into child entities may be selectively restricted from inheritance by such child entities. As with implicit inheritance, selective inheritance is supported by the higher-level schema of entity management system 50, thus permitting selective inheritance to be implemented without modification to the underlying database schema. In the discussion hereinafter, fields capable of being inherited are referred to as "gene" fields, with other fields being referred to as "non-gene" fields. However, it will be appreciated that this terminology should not be used to limit the invention, as other terminology could be used to refer to inheritable and non-inheritable fields or parameters consistent with the invention. FIG. 40 shows an example of how selective inheritance could be used. In this example, a Manager entity 620 and an Executive entity 622 have been modeled. Furthermore, in this example, Managers and Executives are each assigned different types of washrooms. To avoid storing an empty or unused field on an Executive, the Manager's washroom field 624 may be defined as a non-gene, while other fields that may be common to a Manager and an Entity (e.g., a name field 626 and a phone number field 628) may be designated as genes, and thus inherited into an Executive. As such, an Executive may have an executive washroom field 630 (which may or may not be a non-gene for the purposes of this example), and by virtue of washroom field 624 of the Manager being designated as non-gene, the field is kept from being inherited into the Executive. Thus, through selective inheritance, potential confusion and programming errors, which might result in an application when dealing with an entity that has two assigned washrooms, are avoided. In the illustrated implementation, fields or parameters are considered inheritable unless "marked" otherwise. Furthermore, marking a field as not inheritable involves adding an inheritability indicator such as a flag or boolean value to the field that indicates the field is not inheritable, an operation that typically does not require any modification of the database schema. Using the aforementioned entity management system, where fields are implemented as dependent entities that themselves may include dependent entities, a dependent field may be associated with a flag field to indicate a non-inheritable status of the field. As shown in FIG. 41, for example, a mechanism may be used where non-genes are marked as such using a gene field ("isGene") 632, including a stored value of "false," while any field that isn't marked (e.g., name field 626) is assumed to be an inheritable field. This approach reduces the amount of information storage required to support selective inheritance, especially as for many applications the vast majority of fields will be inheritable and only a tiny fraction will need to be marked as non-genes. Also, as represented by phone number field 628, it may also be desirable to support an explicit inheritable indicator for certain fields, e.g., by using a gene field 634 having a stored value of "true." Such explicit fields may be used, for example, if a field that was once designated as non-gene is changed to a gene. In the alternative, program logic may be incorporated into entity management system 50 to delete a gene field in response to changing a non-gene to a gene. FIG. 42 illustrates a mark routine 640 representing the logic used when a field is to be marked as a non-gene. In response to a request to mark a field, block 642 either creates a new gene field dependent on the field to be marked, or obtains an existing gene field if one already exists. Next, block 644 sets the gene field value to "false" to indicate that the field to be marked is not inheritable. Routine 640 is complete. It will be appreciated that similar program logic could be used to mark a field as inheritable. FIG. 43 illustrates a get field routine 650 representing the logic used to control how fields are inherited from a parent class to a child class. In the illustrated implementation, selective inheritance may be handled as an extension of the implicit inheritance functionality of entity management system 50. As such, routine 650 operates substantially in the same manner as get field routine 220 of FIG. 15, with blocks 652-666 operating in substantially the same manner as the corresponding blocks 222-236 of routine 220. However, routine 650 differs from routine 220 in that once a parent entity has been found that owns a requested field (block 658), rather than passing control to block 660 to build a working copy of the requested field for the child entity, block 668 is first executed to determine whether the requested field is marked as a non-gene (not inheritable). If not (indicating that the field is inheritable), control passes to block 660 to build the working copy of the requested field as in routine 220. Otherwise, if the field is not inheritable, control passes to block 666 to return a "NULL" alias, indicating that the field cannot be obtained (i.e., it is restricted from being inherited). It will be appreciated that, in other implementations, fields or parameters may default to non-inheritable. Moreover, other mechanisms, functioning as inheritability indicators for use in identifying a field as inheritable or not may be used, e.g., flags, a centralized data structure, etc. Moreover, an inheritability indicator may stored separate from the field with which it is associated. Furthermore, selective inheritance may be implemented separate of implicit inheritance in other implementations, and implicit inheritance functionality need not be used in some environments where selective inheritance is implemented. Moreover, selective inheritance may be used in environments that do not manage persistent and working representations of entities in the manner described herein. For example, selective inheritance may be used in environments where child entities inherit parameters from parent entities at the time such child entities are created, such that the determination of whether to inherit a field or parameter, as well as the actual operation of inheriting the field or parameter, are performed in association with the creation of a child entity, rather than in association with attempting to access the field or parameter. Other modifications will be apparent to one of ordinary skill in the art. Bi-directi | ||||||
