Views are the normal way to work with data when developing Java servers. A view is basically a named collection of named attributes of a certain type and value.
Views and records (FndRecord
) are related to each other because they share
the same ancestor class,
FndAbstractRecord
, which contains most of the functionality.
You could say that FndRecord
is the generic implementation of FndAbstractRecord
and a generated view is a specific implementation for a certain
operation. With views instead of records there is less implementation code and, maybe
most important, compile-time type safety.
When you generate Java code from your model containing entities and views, those objects become Java classes representing the modeled view. Such a class does not contain any business logic (logic is implemented in handlers), from a developer perspective a view is simply a container for information (a value object using J2EE terms). A view contains attributes (those were also modeled), possibly in some way representing columns in a database table.
Views and attributes contain some functionality used by the framework to control if a record has been modified or not, how it should be serialized and, if the view/attribute is persistent (can be persisted in a persistent storage such as a database), meta-data about how to persist it. Views and attributes also have some functionality that can be used by a developer, those methods will be described later on.
Views are generated into a Java class for each view modeled. The view's
attributes are generated into public final fields in the class. The type
of an attribute is always a sub-class of
FndAttribute
(in
ifs.fnd.record
package). For instance if the modeled attribute type is Text, then the generated
field in the Java class is
FndText
.
In the generated view classes there are also other attributes, called meta-data attributes, inaccessible outside the class. The use of the meta-data attribute is restricted to the Java Server Framework.
If the generated view is the master view of a master-detail relationship, the attribute for the details in the master view is either an array or aggregate class generated specifically for the detail view.
Since the attributes for a view are generated into public fields marked as final (which means that they can only be assigned a value once, when they are created), you cannot set an attribute's value by simply assigning the field a value. The following code will not compile:
PersonInfo person = new PersonInfo(); person.name = new FndText("NAME", "John Smith"); // <-- compile error
Instead you must use the attribute's setValue
and
getValue
methods for manipulating the value. The code above must be written like this:
PersonInfo person = new PersonInfo(); person.name.setValue("John Smith");
It is important to check for null values and non-existent
attributes when retrieving values from attributes. Because if that is not done,
a NullPointerException will likely be thrown and your application fails to do
its work. If an attribute doesn't have a value, then it is null. To check
for that there is a isNull
method on all attributes. Non-existent
attributes are attributes that don't exist, or more precisely, are marked as
non-existent. This means that they will not be included when the view is
returned to the client application. An attribute may be non-existent because a
client application did not send it to the server or because it has explicitly been set
so. To check if an attribute is non-existent (or rather exists) use the exist
method.
In the
ifs.fnd.record
package of the Java Server Framework there are a
number of classes that serves as super-classes for generated views.
FndView
is the top-most base class for generated views. Views modeled simply as view
gets this as super-class. This class itself is a sub-class of
FndAbstractRecord
.
FndPersistentView
is the base-class for all persistent views. That is, views that
are to be stored in and retrieved from a database in a standardized way by the framework. Views
that are child views to entity views gets this as super-class.
FndEntityView
class is the base-class for entity views. In this class three attributes
concerning storage are defined: objVersion, createdBy, and createdDate.
FndLUEntityView
class is the base-class for entity views that operate against logical
units (LUs). Two storage-related attributes are defined here: objId and
objVersion.
A view is more or less a container for attributes. Since it is the attributes that contain data, there are not many operations on views needed by a developer. There are however a few important ones:
setNonExistent
- Sets all attributes contained by the view to
non-existent.
setState
- Sets the state of the record. Used when saving a
view in persistent storage. There are four possible states - queried,
modified, removed and new.
addCondition
- Add a query condition to the view (used when
querying persistent storage for view instances).transformTo
- Moves attributes from a view to another view.
Both views should have a common ancestor.These methods and related concepts will be explained later.
Entity views belong to a special class of views. Entity views are always persistent (can be persisted) and there are framework methods for getting, querying and saving entity views in persistent storage. These operations are available using an entity handler.
Standard generated entity handlers contain the following operations:
get
- return
a single instance of the entity from persistent storage by setting the primary
key attribute value(s).exist
- check for existence of an entity instance.bulkGet
-
return an array of entity instances from persistent storage (basically the same
as repeated calls to get
).query
- return
an array of entity instances from persistent storage satisfying a query condition.populate
-
populate parts of a master-detail structure with data (similar to get
).prepare
- get the default values for a new instance of an LU entity.save
- save
an entity instance in persistent storage. Saving may either insert, update or
delete an existing instance.bulkSave
- save an array of entity instances in persistent storage (basically the same
as repeated calls to save
).importEntity
- recreates an entity structure previously
fetched by get
or query
.There are different types of attributes - a simple attribute contains a simple value (such as a string or a number). Compound attributes contain other views (aggregates or arrays).
This section is extremely important. Do not proceed unless you truly understand these concepts!
A simple attribute can contain a value such as the String "Hello World!", however, it may also be NULL or not have any value at all. If the attribute is NULL, the value returned would always be NULL. You should be particularly careful with NULL values as you may easily get a NullPointerException if you fail to check for NULL values.
Attribute values are always initialized with a NULL value, if the attribute has
not been given a non-NULL value getValue
will return NULL.
An attribute may be non-existent, meaning that the attribute does not participate in the (storage) operation at all. Non-existent attributes are ignored by the framework when reading/writing views to persistent storage.
Useful attribute methods:
exist
- returns true if the attribute is existent.
isSet
- returns true if the attribute has been given a value.
Note that the value given may be NULL.
hasValue
- returns true if the attribute has been given a non-NULL
value.
isNull
- returns true if the attribute value is NULL. (Attribute
may have a NULL value simply because it has not been given a value at all).getValue
- return the attribute value (may return NULL).setValue
- set the attribute value.
setNull
- set the attribute value to NULL.Always check for NULL values before you use the attribute value. The hasValue
method is very useful!
If an Aggregate association marked as Array is modeled between two views, an array
attribute (a subclass of
FndAbstractArray
) is generated on the master view. Array attributes are attributes that
can contain zero or more views (of the same type).
Useful array attribute methods:
add
- add a view to the arrayget
- get a view from a specific position in the arraysize
- returns the number of views in the arrayassign
- copy all views from one array to another
arrayfor (int i = 0; i < arr.size(); i++) { PersonInfo person = arr.get(i); person.title.setNull(); }
If an Aggregate association not marked as Array is modeled between two views, an aggregate
attribute (a subclass of
FndAbstractAggregate
) is generated on the master view. Aggregate attributes contains a
single view. An association of type Reference by-value also corresponds to an
aggregate attribute.
Useful aggregate attribute methods:
getRecord
- return the view contained in the aggregatesetRecord
- set a view on the aggregateA view containing an aggregate attribute has a generated shortcut method that retrieves the detail view from the aggregate. For example, instead of:
ISOCountry country = person.iSOCountry.getRecord();
you can simply write:
ISOCountry country = person.iSOCountry();
A reference (a subclass of
FndCompoundReference
) is a group of simple attributes acting as a key
connecting views in a master-detail relationship. Every persistent view (a
subclass of
FndPersistentView
) has a primaryKey reference, which contains one or more
primary key attributes for the view.
Useful reference methods:
assign
-
copies the attribute values from another referenceisEqualTo
-
checks if the attribute values match the corresponding values in another referenceThe class FndCompoundReference
implements
FndSortField
interface, and as such may be passed as an argument to
FndQueryRecord.setOrderBy
and
FndAbstractArray.sort
methods.