Summary: GigaSpaces JavaSpaces API Plain Old Java Object support - the POJO. This advanced section deals with the annotations and gs.xml mapping file, ways for troubleshooting, considerations, ID generation and usage as well as frequently used code snippets.

POJO Annotations and XML Space Mapping (gs.xml) File Elements

GigaSpaces supports class and field-level annotations. You can define common behavior for all class instances, and specific behavior for class fields.

The Java Annotations is supported since JVM 1.5. For JVM 1.4, you will need to use the XML space mapping (gs.xml) file.
Annotations

Class Level Annotation – @SpaceClass

Annotation Element Name Type Description Default Value
replicate boolean When running in a partial replication mode, a false value for this property will not replicates all objects from this class type to the replica space or backup space. To run in a partial replication mode deploy the space cluster using the following property:
<os-core:space id="space" url="/./space" no-write-lease="true">
 <os-core:properties>
  <props>
   <prop key="cluster-config.groups.group.repl-policy.policy-type">
      partial-replication
   </prop>   
  </props>
 </os-core:properties>
</os-core:space>
.
true
persist boolean When a space is defined as persistent, a true value for this annotation persists objects of this type.

For more details, refer to the Persistency section.

true
fifoSupport enum of FifoSupport To enable FIFO operations, set this attribute to FifoSupport.OPERATION.

For more details, refer to the FIFO operations section.

FifoSupport.NOT_SET
includeProperties String IncludeProperties.IMPLICIT takes into account all POJO fields – even if a get method is not declared with a @SpaceProperties annotation, it is taken into account as a space field.

IncludeProperties.EXPLICIT takes into account only the get methods which are declared with a @SpaceProperties annotation.
IMPLICIT
inheritIndexes boolean Whether to use the class indexes list only, or to also include the super class indexes.
If the class does not define indexes, superclass indexes are used.
Options:
  • false – class indexes only.
  • true – class indexes and superclass indexes.
true

Field Level Annotation – @SpaceProperty

Element Type Description Default Value
nullValue String Specifies that a value be treated as null.  

example:

@SpaceProperty(nullValue="-1" )
public int getEmployeeID()
{
	return employeeID;
}

where -1 functions as a null value.

Field Level Decoration – @SpaceId

The space mapping file element name for @SpaceId is id (see below).

Defines whether this field value is used when generating the Object ID. The field value should be unique – i.e., no multiple objects with the same value should be written into the space (each object should have a different field value). When writing an object into the space with an existing id field value, an EntryAlreadyInSpaceException is thrown. The Object ID is created, based on the id field value.

The @SpaceID annotation cannot be used with multiple fields. You may specify only one field to be used as the @SpaceId field.

If autoGenerate is declared as false, the field is indexed automatically. If autoGenerate is declared as true, the field isn't indexed.
If autoGenerate is true, the field must be of the type java.lang.String.

Element Type Description Default Value
autoGenerate boolean Specifies if the object ID is generated automatically by the space when written into the space. If false, the field is indexed automatically, and if true, the field isn't indexed false

For more details, see the Space Object ID Operations section.

Field Level Decoration – @SpaceIndex

Querying indexed fields speeds up read and take operations. The @SpaceIndex annotation should be used to specify an indexed field. The @SpaceIndex has two attributes:type and path.

  • The index type is determined by the SpaceIndexType enumeration. This is a mandatory attribute when using the @SpaceIndex annotation. The index types options are:
    • BASIC - This index speeds up equality matches (equal to/not equal to).
    • EXTENDED - This index speeds up comparison matches (bigger than/less than).
    • NONE - Indicates no index type is set, and default should be used.
  • The path() attribute represents the path of the indexed property within a nested object.

Examples:

The @SpaceIndex example
@SpaceClass
public class Person
{
    private String lastName;
    private String firstName;
    private Integer age;

    ...
    @SpaceIndex(type=SpaceIndexType.BASIC)
    public String getFirstName() {return firstName;}
    public void setFirstName(String firstName) {this.firstName = firstName;}


    @SpaceIndex(type=SpaceIndexType.EXTENDED)
    public String getAge() {return age;}
    public void setAge(String age) {this.age = age;}
}
The @SpaceIndex using path example
@SpaceClass
public static class Person {
    private int id;
    private Info personalInfo;
    private String description;
    //getter and setter methods
    ... 

    // this defines and EXTENDED index on the personalInfo.socialSecurity property
    @SpaceIndex(path = "socialSecurity", type = SpaceIndexType.EXTENDED)
    public Info getPersonalInfo() {
         return personalInfo;
    }
}

public static class Info implements Serializable {
	private String name;
	private Date birthday;
	private long socialSecurity;
	//getter and setter methods
}

See the Indexing section for details.

It is highly recommended to index fields used for matching/query. Without the proper index (BASIC or EXTENDED ), the read/readMultiple/take/takeMultiple operations response time might be affected.

Field Level Decoration – @SpaceVersion

This specifies a get method for holding the version ID. This field should be an int data type.

The @SpaceVersion must be an int data type.

Field Level Decoration - @SpacePersist

This specifies a getter method for holding the persistency mode of the object overriding the class level persist declaration. This field should be of the boolean data type.
If the persist class level annotation is true, all objects of this class type will be persisted into the underlying data store (Mirror, ExternalDataSource, Storage Adapter).

When using this option, you must have the space class level persist decoration specified.

Field Level Decoration - @SpaceRouting

The @SpaceRouting annotation specifies a get method for the field to be used to calculate the target space for the space operation (read , write...). The @SpaceRouting field value hash code is used to calculate the target space when the space is running in partitioned mode.
See more details at the Data-Partitioning section.

For details about scaling a running space cluster in runtime see the Dynamic Partitioning section.

Field Level Decoration - @SpaceLeaseExpiration

The @SpaceLeaseExpiration annotation specifies a get and a set method for holding the timestamp of when the instance's lease expires (this is a standard Java timestamp based on the 1/1/1970 epoch). This property should not be populated by the user code. The space will populate this property automatically based on the lease time given by the user when writing the object.
When using an external data source, you can choose to persist this value to the database. Subsequently, when data is reloaded from the external data source (at startup time for example), the space will filter out instances whose lease expiration timestamp has already passed. This field should be a long data type.

Here is how you can load an object into the space via the External Data source with a specific lease:
Have the @SpaceLeaseExpiration decoration on a getter method for a field that will hold the object lease. Usually this will be set by GigaSpaces , but when loading the object you will set it yourself.

@SpaceClass (persist=true)
public class MyData {
    private long lease;
	.............

    @SpaceLeaseExpiration
    public long getLease()
    {
        return lease;
    }
    public void setLease(long lease) {
        this.lease = lease;
    }
}

when loading the object into the space via the External Data source you should set this field lease value - with the example below the loaded object lease will be 10 seconds:

public DataIterator<MyData> initialLoad() throws DataSourceException {
    List<MyData> initData = new ArrayList<MyData>();
    // load the space with some data
    MyData obj = new MyData();
    obj.setWhatEver(...);
    obj.setLease(System.currentTimeMillis() + 10000);
    initData.add(obj);
    return new MyDataIterator(initData);
}

Once an object has been loaded/written into the space you can also change the lease using the Gigaspace. write(T entry, long lease, long timeout, int modifiers) method.

Field Level Decoration - @SpaceExclude

The @SpaceExclude annotation instructs the client to ignore the fields using this annotation, so that they are not stored within the space.

  • When IncludeProperties is defined as IMPLICIT as part of the @SpaceClass annotation, @SpaceExclude should usually be used. This is because IMPLICIT instructs the system to take all POJO fields into account.
  • When IncludeProperties is defined as EXPLICIT, there is no need to use @SpaceExclude.
  • @SpaceExclude can still be used, even if IncludeProperties is not defined.

POJO Class Example – Person and Employee

This example uses the @SpaceId, @SpaceRouting, @SpaceClass, replicate, persist, @SpaceVersion, @SpaceProperty and SpaceIndex annotations as part of the Person and Employee classes:

Person
package com.j_spaces.examples.hellospacepojo;
import com.gigaspaces.annotation.pojo.*;

@SpaceClass(replicate=true,persist=false)
public class Person {
    private String	lastName;
    private String	firstName;
    public Person(){}
    public Person(String lastName, String firstName){
        this.lastName = lastName;
        this.firstName = firstName;
    }
    @SpaceIndex(type=SpaceIndexType.BASIC)
    public String getFirstName(){return firstName;}
    public void setFirstName(String firstName)
          {this.firstName = firstName;}
    public String getLastName(){return lastName;}
    public void setLastName(String name) {this.lastName = name;}
}
Employee
package com.j_spaces.examples.hellospacepojo;

import com.gigaspaces.annotation.pojo.SpaceClass;
import com.gigaspaces.annotation.pojo.SpaceId;
import com.gigaspaces.annotation.pojo.SpaceRouting;
import com.gigaspaces.annotation.pojo.SpaceVersion;

@SpaceClass(replicate=true,persist=false)
public class Employee extends Person
{
    private Integer employeeID;
    private int versionID;
	
    public Employee(){}
    public Employee(Integer employeeID) {
        this.employeeID = employeeID;
    }
    public Employee(String lastName, Integer employeeID) {
        this.employeeID = employeeID;
        setLastName(lastName);
    }
	
    @SpaceId
    @SpaceRouting
    public Integer getEmployeeID(){return employeeID;}

    public void setEmployeeID(Integer employeeID) {
        this.employeeID = employeeID;
    }
    public String toString() {
        return super.toString() + ", \temployeeID: "+ employeeID ;
    }

    @SpaceVersion
    public int getVersionID() {return versionID;}
    public void setVersionID(int versionID) {this.versionID = versionID;}
}

Space Mapping XML File -- gs.xml

The space mapping configuration file gs.xml allows you to define space class metadata when using a POJO class with getter or setter methods. Space mapping files are also required when using POJO objects with the ExternalDataSource interface. The gs.xml configuration file is loaded when the application and space are started. gs.xml files can be edited to include GigaSpaces specific attributes.

The gs.xml file is mainly used with 1.4 JVM which does not support the Java Annotations.

gs.xml Location

The *.gs.xml file can reside in one of two locations:

  • The <CLASSPATH>/config/mapping folder. In this case, the gs.xml file can include decorations for multiple classes and can have any name. For example, the mapping file could be placed at "mpApp/config/mapping/myapplication.gs.xml", where the mpApp folder is part of the application CLASSPATH. You may have multiple gs.xml files located at the <CLASSPATH>/config/mapping folder.
  • In the same folder as the POJO class file. In this case, the gs.xml file should use the same class name as the file prefix. For example, if a POJO class is located at "mpApp/my/package/MyPojo.class" then the mapping file must located at "mpApp/my/package/MyPojo.gs.xml".

The replicate and persist attributes must be defined (either true or false), as part of the class element.

gs.xml Example

When using the version, id and routing elements, place these in the gs.xml file in the following order:

  1. version
  2. id
  3. routing

Below is an example for an Employee class and a Person class XML configuration file named mapping.gs.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE gigaspaces-mapping PUBLIC "-//GIGASPACES//DTD GS//EN" 
    "http://www.gigaspaces.com/dtd/7_1/gigaspaces-metadata.dtd">
<gigaspaces-mapping>
    <class name="com.j_spaces.examples.hellospacepojo.Employee" persist="false" replicate="false">
        <version name="versionID" />
        <id name="employeeID" auto-generate="false" />
        <routing name="employeeID" />
        <reference
            class-ref="com.j_spaces.examples.hellospacepojo.Person" />
    </class>
    <class name="com.j_spaces.examples.hellospacepojo.Person" persist="false" replicate="false">
        <property name="lastName" index="BASIC" />
        <property name="firstName" index="BASIC" />
    </class>
</gigaspaces-mapping>
The Employee class uses the <reference> tag to inherit metadata from the Person Class.

XML Tags

Class Level Tags

  • <class> – a class and the associated Java class ClassDescriptor encapsulate meta data information of a concrete class.
    Attribute Description
    name Contains the full qualified name of the specified class. Because this attribute is of the XML type ID, there can only be one class-descriptor per class.
    persist This field indicates the persistency mode of the object. When a space is defined as persistent, a true value for this attribute will persist objects of this type.

    For more details, refer to the Persistency section.

    replicate This field indicates the replication mode of the object. When a space is defined as replicated, a true value for this attribute will replicate objects of this type.

    For more details, refer to the Replication section.

    fifo-support To enable FIFO operations, set this attribute to one of the FifoSupport enumeration values.

    For more details, refer to the FIFO operations section.

Field Level Tags

All the fields are written automatically into space. If the field is a reference to another object, it has to be Serializable and it will be written into space as well. Only the fields which need special space behavior need to be specified in the gs.xml file. Specify the fields which are id's, indexes or need exclusions, etc.

  • <property> - contains mapping info for a primitive type attribute of a persistent class.
    Attribute Description
    name Holds the name of the persistent class attribute.
    index Indicates which fields are indexed in the space. The first indexed member is used for hashing. Querying indexed fields speeds up read and take operations.
  • <reference> - contains mapping information for an attribute of a class that is not primitive, but references another entity object.
  • <null-value> - a value that will represent a null. Relevant for primitive fields (int, long).
    <class name="com.j_spaces.examples.hellospacepojo.Person" 
            persist="false" replicate="false">
        <property name="int_Field" null-value="-1" />
        <property name="long_Field" null-value="-1" />
    </class>
  • <class-ref> - contains the full qualified name of the specified class.
  • <id> - defines whether this field value is used when generating the object ID.
    Attribute Description
    name Specifies a get method that allows identification of the id element in the space.
    auto-generate Specifies if the object ID is generated automatically by the space when written into the space. If false, the field is indexed automatically, and if true, the field isn't indexed.
  • <version> - saves the POJO's version in the space. This must be an int data type field.
    Attribute Description
    name Specifies a get method for holding the version's ID.
  • <persist> - allows you to specify whether a POJO is or isn't saved inside the space.
    Attribute Description
    name Specifies a get method for holding the persist flag.
  • <routing> - Determines the target space for the operation with using partitioned space.
    Attribute Description
    name Specifies a get method that allows identification of the routing element in the space.
  • <exclude> - causes the POJO field under this element to be excluded, and not be saved in the space.
    • If you specify a field name that exists as part of the property element, this field is excluded.
    • If the field name doesn't exist as part of the property element, this means that this field name is part of the Person class, and you do not want it to be saved in the space.
For details about scaling a running space cluster in runtime see the Dynamic Partitioning section.

generateGsXml Utility - Generating the gs.xml File

When a Hibernate class-to-database mapping configuration file (hbm) exists for the classes for which a space mapping configuration file gs.xml is required, a simple utility can be used to generate the gs.xml file from the hbm file.

The utility, generateGsXml, was located at <GigaSpaces Root>\bin till XAP 6.5 and it was move to OpenSpaces.org as an opensource project in XAP 6.5.

The generated space configuration file gs.xml should be located at <CLASSPATH>\config\mapping folder. GigaSpaces client and space load these files when the application and space are started.

generateGsXml Utility Options

Set the Environment variables as follows:

  • POJO_CLASSPATH - The path for the POJOs class file.
  • HIBERNATE_HOME - The path for the Hibernate configuration file and *.hbm files.

The generateGsXml command has the following parameters:

Parameter Required/Optional Description Default Value
-beanName Required if isHibernate is false. The bean (POJO) name. Represents the full path of the POJO's name.  
-outputDir required The output directory for all the generated gs.xml files.  
-is
Hibernate
optional Indicates whether to generate gs files from all *.hbm hibernate file in classpath. false
-mapping
Type
optional The mapping type can have a space value or a map value. space
-isFifo optional Indicates whether to use FIFO for all the beans. false
-isPersist optional Indicates whether to use persistent for all the beans. true
-is
Replicate
optional Indicates whether to use replicate for all the beans. true
-hibernate
ConfigFile
optional The hibernate configuration file if isHibernate is true. /hibernate.cfg.xml.
-override
File
optional Indicates whether to override an existing file with the same filename. false, meaning it will create a new file using the .new suffix.
-inherit
Indexes
optional Two values can be chosen:
  • hierarchy - takes into account the declared indexes that are set to true, and all their superclasses.
  • instance - takes into account the instance's indexes; or if it's indexes are false, takes into account the first superclass that contains indexes that are true.
true

Examples

generateGsXml -beanName com.j_spaces.examples.hellospacepojo.SimpleBean  -outputDir D:\dev\gigaspaces\
generateGsXml -isHibernate true  -outputDir D:\dev\gigaspaces\ -hibernateConfigFile hibernate.cfg.xml

User Defined Space Class Fields

You may use user defined data types (non-primitive data types) with your Space class. These should implement the Serializable interface.
The user defined fields cannot be used by default for queries. You should provide a getter and a setter method for these as part of their parent Space class.
See example below:

The User defined Class
public class MyUserDefinedClass implements Serializable{
	String fieldA;
	String fieldB;
	public String getFieldA() {
		return fieldA;
	}
	public void setFieldA(String fieldA) {
		this.fieldA = fieldA;
	}
	public String getFieldB() {
		return fieldB;
	}
	public void setFieldB(String fieldB) {
		this.fieldB = fieldB;
	}
}

The Space class will have the user defined data type fields getter and setter methods.
You can index these fields as any other Space class fields to allow fast search when performing read or take operations:

The Space Class with the User defined Class fields getters and setters
@SpaceClass
public class Trade implements Serializable {
    
    String _tradeId;
    String _instrument;
    String _accountId;
    MyUserDefinedClass customField = null;
    
    public Trade() {
        
    }

    @SpaceIndex(type=SpaceIndexType.BASIC)
    public String getMyClassFieldA()
    {
    	if (customfield == null) return null;
    	return customfield.getFieldA();
    }

    @SpaceIndex(type=SpaceIndexType.BASIC)
    public String getMyClassFieldB()
    {
    	if (customfield == null) return null;
    	return customfield.getFieldB();
    }

    public void setMyClassFieldA(String value)
    {
    	customfield.setFieldA(value);
    }

    public void setMyClassFieldB(String value)
    {
    	customfield.setFieldB(value);
    }
    ....
}

The code to query the Space class will look like this:

Query User defined Class
SQLQuery<Trade> query = new SQLQuery(Trade.class , "myClassFieldA= 'SomeValue' or myClassFieldB = 'someValue2'");
Trade trades[] = _gigaSpace.readMultiple(query ,Integer.MAX_VALUE);

Troubleshooting

Using Logging

Use the com.gigaspaces.pojo.level = ALL as part of the logging file located by default at <GigaSpaces Root>\config\gs_logging.properties, to debug the POJO metadata load and conversion to space object. Having the <GigaSpaces Root> as part of the application CLASSPATH turns on the POJO debug activity at the client side.

When the POJO logging is turned on, the following should appear at the client side console when a class is introduced to the space:

FINEST [com.gigaspaces.pojo]: The annotation structure of class com.j_spaces.examples.hellospacepojo.Employee is : 
name = com.j_spaces.examples.hellospacepojo.Employee
fieldNames = [firstName, lastName, employeeID, versionID]
fieldPks = [employeeID]
fieldAutoPkGen = []
fieldIndexs = [employeeID, firstName, lastName]
hashBasedKey = []
version = [versionID]
lazyDeserialization = []
payload = []
serializationTypeFields = {}
defaultNullValueFields = {firstName=null, lastName=null}
refClasses = [com.j_spaces.examples.hellospacepojo.Person]
persist class = false
persist instance = []
routing field name = [employeeID]
timetolive = 9223372036854775807
fifo = false
inheritIndexes = true
includeProperties = IMPLICIT
replicate true
fieldTypes = null
mappingType = space
serializationType = 0
exclude = []

A converted object logging output looks like this:

FINE [com.gigaspaces.pojo]: ExternalEntry after converter is: 
	 ClassName: com.j_spaces.examples.hellospacepojo.Employee
 
	 Field Name:  firstName 
	 Field Type:  java.lang.String 
	 Field Value: first name1 
	 Field Indexed: false
 
	 Field Name:  lastName 
	 Field Type:  java.lang.String 

	 Field Value: Last Name1 
	 Field Indexed: false
 
	 Field Name:  employeeID 
	 Field Type:  java.lang.Integer 
	 Field Value: 1 
	 Field Indexed: true

Using The GUI

Use the GS-UI space class view to examine the POJO meta data. Make sure the annotations/xml decorations have been introduced to the space correctly i.e. correct class name, field names, field types, indexes, routing field, replication mode and FIFO mode etc.

GigaSpaces.com - Legal Notice - 3rd Party Licenses - Site Map - API Docs - Forum - Downloads - Blog - White Papers - Contact Tech Writing - Gen. by Atlassian Confluence