Cloud Software Group, Inc. EBX®
Documentation > Developer Guide > Introduction
Navigation mode Documentation > Developer Guide > Introduction

# Mapping to Java

## How to access data from Java?

### Read access

Data can be read from various generic Java classes, mainly `Adaptation` and `ValueContext`. The getter methods for these classes return objects that are typed according to the mapping rules described in the section Mapping of data types.

### Write access

Data updates must be performed in a well-managed context:

- In the context of a procedure execution, by calling the methods `setValue...` of the interface `ValueContextForUpdate`, or

- During the user input validation, by calling the method `setNewValue` of the class `ValueContextForInputValidation`.

### Modification of mutable objects

According to the mapping that is described in the Mapping of data types section, some accessed Java objects are mutable objects. These are instances of `List` , `Date` or any JavaBean. Consequently, these objects can be locally modified by their own methods. However, such modifications will remain local to the returned object unless one of the above setters is invoked and the current transaction is successfully committed.

## Transactions and concurrency

### Concurrency

At the dataspace level | In a single dataspace, the system supports running only one single read-write `Procedure` and multiple concurrent `ReadOnlyProcedure`s. Concurrent accesses outside any `Procedure` are also supported.
At the repository level | At the repository level, concurrency is limited for only some specific operations. For example (non-exhaustive list): A data model publication excludes many operations. A dataspace merge excludes write operations on the two dataspaces involved in the merge.

### Query snapshot isolation

The following table defines the properties related to query isolation. Note that a query result is represented in the Java API by either a `QueryResult` or a `RequestResult`:

Queries outside of a `Procedure` | Data is frozen at the time of fetching the query result. More precisely, a query result accesses only committed data as of the last committed transaction at the time of fetching this result. The content of this result never changes afterwards. A query outside of a `Procedure` can be considered as a self-containing `ReadOnlyProcedure`.
Queries inside of a `Procedure`, in the same dataspace as the `Procedure` underlying dataspace | The query result reflects the last committed state before the Procedure starts and the changes that occurred in the `Procedure` previously to the query result fetch. The content of this result never changes afterwards, whatever happens in the `Procedure`.
Queries inside of a `Procedure`, in another dataspace | The consistency is guaranteed at the repository level, so the query result reflects the last committed state before the `Procedure` starts. The content of this result never changes after the query is fetched, whatever happens in the whole repository.

### Adaptation objects

In Java, a persistent dataset or a persistent record are both represented by an instance of the `Adaptation` class.

The following table defines the properties related to `Adaptation` objects.

Immutability | An `Adaptation` object instance is immutable. Therefore, the client code should not "hold" an `Adaptation` object for a long time (in particular beyond a transaction boundaries). However, it is possible to invoke the method `Adaptation.getUpToDateInstance`.
Fetch | If an `Adaptation` is fetched from a `QueryResult`, then the snapshot isolation rules described in the previous section apply. Otherwise, if an `Adaptation` is fetched from a running `Procedure`, it reflects the last committed state before the Procedure starts. Otherwise, outside of a `QueryResult` or a running `Procedure`, the `Adaptation` reflects the state of the record on its fetch-time. ##### See also `AdaptationHome.findAdaptationOrNull` `AdaptationTable.lookupAdaptationByPrimaryKey`

## Mapping of data types

This section describes how XML Schema type definitions and element declarations are mapped to Java types.

### Simple data types

#### Basic rules for simple data types

Each XML Schema simple type corresponds to a Java class; the mapping is documented in the table XML Schema built-in simple types.

##### See also

- `SchemaNode.createNewOccurrence`

#### Multiple cardinality on a simple element

If the attribute `maxOccurs` is greater than 1, then the element is an aggregated list and the corresponding instance in Java is an instance of `java.util.List`.

Elements of the list are instances of the Java class that is determined from the mapping of the simple type (see previous section).

### Complex data types

#### Complex type definitions without a class declaration

By default (no attribute `osd:class`), a terminal node of a complex type is instantiated using an internal class. This class provides a generic JavaBean implementation. However, if a custom client Java code must access these values, use a custom JavaBean. To do so, use the `osd:class` declaration described in the next section.

You can transparently instantiate, read and modify the mapped Java object, with or without the attribute `osd:class`, by invoking the methods `SchemaNode.createNewOccurrence`, `SchemaNode.executeRead` and `SchemaNode.executeWrite`.

#### Mapping of complex types to custom JavaBeans

You can map an XML Schema complex type to a custom Java class. This is done by adding the attribute `osd:class` to the complex node definition. Unless the element has `xs:maxOccurs > 1`, you must also specify the attribute `osd:access` for the node to be considered a terminal node. If the element has `xs:maxOccurs > 1`, it is automatically considered to be terminal.

The custom Java class must conform to the JavaBean protocol. This means that each child of the complex type must correspond to a JavaBean property of the class. Additionally, each JavaBean property must be a read-write property, and its implementation must ensure that the value set by the setter method is returned, as-is, by the getter method. Contextual computations are not allowed in these methods.

#### Example

In this example, the Java class `com.carRental.Customer` must define the methods `getFirstName()` and `setFirstName(String)`.

A JavaBean can have a custom user interface within TIBCO EBX®, by using a ``UIBeanEditor``.

    <xs:element name="customer" osd:access="RW">
      <xs:complexType name="subscriber" osd:class="com.carRental.Customer">
    	<xs:sequence>
    	  <xs:element name="firstName" type="xs:string"/>
    	  ...
    	</xs:sequence>
      </xs:complexType>
    </xs:element>

#### Multiple cardinality on a complex element

If the attribute `maxOccurs` is greater than 1, then the corresponding instance in Java is:

- An instance of `java.util.List` for an aggregated list, where every element in the list is an instance of the Java class determined by the mapping of simple types, or

- An instance of `AdaptationTable`, if the property `osd:table` is specified.

## Java bindings

Java bindings support generating Java types that reflect the structure of the data model. The Java code generation can be done in the user interface. See Generating Java bindings.

### Benefits

Ensuring the link between XML Schema structure and Java code provides a number of benefits:

- Development assistance: Auto-completion when you type an access path to parameters, if it is supported by your IDE.

- Access code verification: All accesses to parameters are verified at code compilation.

- Impact verification: Each modification of the data model impacts the code compilation state.

- Cross-referencing: By using the reference tools of your IDE, you can easily verify where a parameter is used.

Consequently, it is strongly encouraged that you use Java bindings.

### XML declaration

The specification of the Java types to be generated from the data model is included in the main schema.

Each binding element defines a generation target. It must be located at, in XPath notation, `xs:schema/xs:annotation/xs:appinfo/ebxbnd:binding`, where the prefix `ebxbnd` is a reference to the namespace identified by the URI `urn:ebx-schemas:binding_1.0`. Several binding elements can be defined if you have different generation targets.

The attribute `targetDirectory` of the element `ebxbnd:binding` defines the root directory used for Java type generation. Generally, it is the directory containing the project source code, `src`. A relative path is interpreted based on the current runtime directory of the VM, as opposed to the XML schema.

See bindings XML Schema.

#### XML bindings example

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    	xmlns:ebxbnd="urn:ebx-schemas:binding_1.0">
    	<xs:annotation>
    		<xs:appinfo>
    			<!-- The bindings define how this schema will be represented in Java.
    			Several <binding> elements may be defined, one for each target. -->
    			<ebxbnd:binding
    				targetDirectory="../_ebx-demos/src-creditOnLineStruts-1.0/">
    				<javaPathConstants typeName="com.creditonline.RulesPaths">
    					<nodes root="/rules" prefix="" />
    				</javaPathConstants>
    				<javaPathConstants typeName="com.creditonline.StylesheetConstants">
    					<nodes root="/stylesheet" prefix="" />
    				</javaPathConstants>
    			</ebxbnd:binding>
    		</xs:appinfo>
    	</xs:annotation>
    	...
    </xs:schema>

Java constants can be defined for XML schema paths. To do so, generate one or more interfaces from a schema node, including the root node `/`. The example generates two Java path constant interfaces, one from the node `/rules` and the other from the node `/stylesheet` in the schema. Interface names are described by the element `javaPathConstants` with the attribute `typeName`. The associated node is described by the element `nodes` with the attribute `root`.

Documentation > Developer Guide > Introduction