EBX® data model allows to define triggers and computed fields. It also provides auto-incremented fields
By default, data is read and persisted in the XML repository. Nevertheless, data may be the result of a computation and/or external database access, for example, an RDBMS or a central system.
EBX® allows taking into account other data in the current dataset context.
This is made possible by defining computation rules.
A computation rule is specified in the data model using the osd:function
element (see example below).
The value of the class attribute must be the qualified name of a Java class that implements the Java interface ValueFunction
Additional parameters may be specified at the data model level, in which case the JavaBean convention is applied.
Example:
<xs:element name="computedValue"> <xs:annotation> <xs:appinfo> <osd:function class="com.foo.ComputeValue"> <param1>...</param1> <param...n>...</param...n> </osd:function> </xs:appinfo> </xs:annotation> ... </xs:element>
In some cases, it can be useful to disable the validation of computed values if the execution of a function is time-consuming. Indeed, if the function is attached to a table with N records, then it will be called N times when validating this table. The property osd:disableValidation= "true"
specified in the data model allows to disable the validation of a computed value (see example below).
Example:
<xs:element name="computedValue" osd:disableValidation="true"> <xs:annotation> <xs:appinfo> <osd:function class="com.foo.ComputeValue"> ... </osd:function> </xs:appinfo> </xs:annotation> ... </xs:element>
Datasets or table records can be associated with methods that are automatically executed when some operations are performed, such as creations, updates, or deletions.
In the data model, these triggers must be declared under the annotation/appinfo
element using the osd:trigger
element.
For dataset triggers, a Java class that extends the abstract class
must be declared inside the element InstanceTrigger
osd:trigger
.
In the case of dataset triggers, it is advised to define annotation/appinfo/osd:trigger
tags just under the root
element of the data model.
Example:
<xs:element name="root" osd:access="--"> ... <xs:annotation> <xs:appinfo> <osd:trigger class="com.foo.MyInstanceTrigger"> <param1>...</param1> <param...n>...</param...n> </osd:trigger> </xs:appinfo> </xs:annotation> ... </xs:element>
For the definition of table record triggers, a Java class that extends the abstract class
must be defined inside the TableTrigger
osd:trigger
element. It is advised to define the annotation/appinfo/osd:trigger
elements just under the element describing the associated table or table type.
Examples:
On a table element:
<xs:element name="myTable" type="MyTableType" minOccurs="0" maxOccurs="unbounded"> <xs:annotation> <xs:appinfo> <osd:table> <primaryKeys>/key</primaryKeys> </osd:table> <osd:trigger class="com.foo.MyTableTrigger" /> </xs:appinfo> </xs:annotation> </xs:element>
On a table type element:
<xs:complexType name="MyTableType"> ... <xs:annotation> <xs:appinfo> <osd:trigger class="com.foo.MyTableTrigger"> <param1>...</param1> <param...n>...</param...n> </osd:trigger> </xs:appinfo> </xs:annotation> ... </xs:complexType>
As additional parameters can be defined, the implemented Java class must conform to the JavaBean protocol. In the example above, the Java class must define the methods: getParam1()
, setParam1(String)
, getParamX()
, setParamX(String)
, etc.
It is possible to define auto-incremented values. Auto-incremented values are only allowed inside tables, and they must be of the type xs:int
or xs:integer
.
An auto-increment is specified in the data model using the element osd:autoIncrement
under the element annotation/appinfo
.
Example:
<xs:element name="autoIncrementedValue" type="xs:int"> <xs:annotation> <xs:appinfo> <osd:autoIncrement /> </xs:appinfo> </xs:annotation> </xs:element>
Also, there are two optional elements, start
and step
:
The start
attribute specifies the first value for this auto-increment. If this attribute is not specified, then the value 1
is set by default.
The step
attribute specifies the step for the next value to be generated by the auto-increment. If this attribute is not specified, then the value 1 is set by default.
Example:
<xs:element name="autoIncrementedValue" type="xs:int"> <xs:annotation> <xs:appinfo> <osd:autoIncrement> <start>100</start> <step>5</step> </osd:autoIncrement> </xs:appinfo> </xs:annotation> </xs:element>
A field specifying an osd:autoIncrement
has the following behavior:
The computation and allocation of the field value are performed whenever a new record is inserted and the field value is undefined.
No allocation is performed if a programmatic insertion already specifies a non-null
value. For example, if an archive import or an XML import specifies the value, that value is preserved.
Consequently, the allocation is not performed for a record insertion in occulting or overwriting modes.
A newly allocated value is, whenever possible, unique in the scope of the repository. More precisely, the uniqueness of the allocation spans over all the datasets of the data model, and it also spans over all the dataspaces. The latter case allows the merge of a dataspace into its parent with a reasonable guarantee that there will be no conflict if the osd:autoIncrement
is part of the records' primary key.
This principle has a very specific limitation: when a mass update transaction that specifies values is performed at the same time as a transaction that allocates a value on the same field, it is possible that the latter transaction will allocate a value that will be set by the first transaction (there is no locking between different dataspaces).
Internally, the auto-increment value is stored in the 'Auto-increments' table of the repository. In the user interface, it can be accessed by administrators in the 'Administration' area. This field is automatically updated so that it defines the greatest value ever set on the associated osd:autoIncrement
field, in any instance or dataspace in the repository. This value is computed, taking into account the max value found in the table being updated.
In certain cases, for example when multiple environments have to be managed (development, test, production), each with different auto-increment ranges, it may be required to avoid this "max value" check. This particular behavior can be achieved using the disableMaxTableCheck
property. It is generally not recommended to enable this property unless it is absolutely necessary, as this could generate conflicts in the auto-increment values. However, this property can be set in the following ways:
Locally, by setting a parameter element in the auto-increment declaration: <disableMaxTableCheck>true</disableMaxTableCheck>
,
For the whole data model, by setting <osd:autoIncrement disableMaxTableCheck="true"/>
in the element xs:appinfo
of the data model declaration, or
Globally, by setting the property ebx.autoIncrement.disableMaxTableCheck=true
in the EBX® main configuration file.
When this option is enabled globally, it becomes possible to create records in the table of auto-increments, for example by importing from XML or CSV. If this option is not selected, creating records in the table of auto-increments is prohibited to ensure the integrity of the repository.