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, UID generation and usage as well as frequently used code snippets.
POJO Annotations and XML Space Mapping (gs.xml) File ElementsGigaSpaces supports class and field-level annotations. You can define common behavior for all class instances, and specific behavior for class fields.
Annotations
Class Level Annotation – @SpaceClass
Field Level Annotation – @SpaceProperty
example: @SpaceProperty(nullValue="-1" , index=IndexType.BASIC} public int getEmployeeID() { return employeeID; } where -1 functions as a null value.
Field Level Decoration – @SpaceIdThe space mapping file element name for @SpaceId is id (see below). Defines whether this field value is used when generating the Object UID. 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 UID is created, based on the id field value.
If autoGenerate is declared as false, the field is indexed automatically. If autoGenerate is declared as true, the field isn't indexed.
Field Level Decoration – @SpaceVersionThis specifies a get method for holding the version ID. This field should be an int data type.
Field Level Decoration - @SpacePersistThis 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.
Field Level Decoration - @SpaceRoutingThe @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. Field Level Decoration - @SpaceExcludeThe @SpaceExclude annotation instructs the client to ignore the fields using this annotation, so that they are not stored within the space.
POJO Class Example – Person and EmployeeThis example uses the @SpaceId, @SpaceRouting, @SpaceClass, replicate, persist, fifo, @SpaceVersion, @SpaceProperty and index annotations as part of the Person and Employee classes:
Person
package com.j_spaces.examples.hellospacepojo; import com.gigaspaces.annotation.pojo.SpaceClass; import com.gigaspaces.annotation.pojo.SpaceProperty; import com.gigaspaces.annotation.pojo.SpaceProperty.IndexType; @SpaceClass(replicate=true,persist=false,fifo=false) public class Person { private String lastName;private String firstName; public Person(){} public Person(String lastName, String firstName){this.lastName = lastName;this.firstName = firstName;} @SpaceProperty(index=IndexType.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,fifo=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.
gs.xml LocationThe *.gs.xml file can reside in one of two locations:
gs.xml ExampleWhen using the version, id and routing elements, place these in the gs.xml file in the following order:
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/6_0/gigaspaces-metadata.dtd"> <gigaspaces-mapping> <class name="com.j_spaces.examples.hellospacepojo.Employee" persist="false" replicate="false" fifo="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" fifo="false" > <property name="lastName" index="BASIC" /> <property name="firstName" index="BASIC" /> </class> </gigaspaces-mapping>
XML TagsClass Level Tags
Field Level Tags
generateGsXml Utility - Generating the gs.xml FileWhen 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 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 OptionsSet the Environment variables as follows:
The generateGsXml command has the following parameters:
ExamplesgenerateGsXml -beanName com.j_spaces.examples.hellospacepojo.SimpleBean -outputDir D:\dev\gigaspaces\
generateGsXml -isHibernate true -outputDir D:\dev\gigaspaces\ -hibernateConfigFile hibernate.cfg.xml
POJO UID Generation and Usage ScenariosInserting POJOs into the SpaceYou can insert POJOs into the space using the write() and writeMultiple() methods. When a new object is inserted into the space, it embeds a unique ID - called the UID. The UID can be generated explicitly by the client using a unique value generated by the application business logic or using a sequencer running within the space. The space UID for POJOs can be created in three different ways:
Fetching POJOs from the SpacePOJOs can be fetched from the space using the methods read(), readMultiple(), readIfExists(), take(), takeMultiple(), and takeIfExists(). A POJO can be fetched from the space in different ways:
Examples
Reading a POJO using an ID
With the following code example, the EmployeeID field is decorated using: <id name="employeeID" auto-generate="false" /> Note the EmployeeID field should be populated with the original value used when the object has been written into the space, and not with the UID of the object. GigaSpace space; Employee templ = new Employee(); templ.setEmployeeID("myEmployeeID"); Employee ret = space.read(templ); The following shows how to read Multiple objects using their ID: GigaSpace space; String ChildClassName = Child.class.getName(); //Converting back from list of UIDs to IDs for (int i=0;i<childs_uid.length;i++) { childs_uid[i] = ClientUIDHandler.createUIDFromName(childs_uid[i] ,ChildClassName ); } ExternalEntry templateUIDs = new ExternalEntry (childs_uid); Object results[] = space.readMultiple(templateUIDs , Integer.MAX_VALUE); childs = new Child[results.length]; for (int i=0;i<results.length ; i++) { // converting ExternalEntry to Object - this is a local call! childs [i] =(Child) ((ExternalEntry) results[i]).getObject(space.getSpace()); } Parent Child Relationship In some cases, you might want to store Objects within the space that include references to other space Objects – i.e. an object graph. The example code below demonstrates how ID operations handle relationships between objects. The example writes 1000 parent-child graphs into the space.
This eventually returns the 5 matching graphs. The full example source code can be downloaded here. Child class:
Child
package com.j_spaces.examples.parentchild; import com.gigaspaces.annotation.pojo.SpaceClass; import com.gigaspaces.annotation.pojo.SpaceId; import com.gigaspaces.annotation.pojo.SpaceProperty; import com.gigaspaces.annotation.pojo.SpaceProperty.IndexType;; @SpaceClass public class Child { public Child(){} public Child(String id, String parentUID) { this.parentUID = parentUID; this.id = id; } public String parentUID; public Long field; public String id; public String toString() { return "ID:" + id + " data:" + field; } @SpaceProperty(index=IndexType.BASIC) public Long getField() { return field; } public void setField(Long field) { this.field = field; } @SpaceId (autoGenerate = false) public String getId() { return id; } public void setId(String id) { this.id = id; } @SpaceProperty(index=IndexType.BASIC) public String getParentUID() { return parentUID; } public void setParentUID(String parentUID) { this.parentUID = parentUID; } } Parent class:
Parent
package com.j_spaces.examples.parentchild; import java.rmi.RemoteException; import org.openspaces.core.GigaSpace; import net.jini.core.entry.UnusableEntryException; import net.jini.core.transaction.TransactionException; import com.gigaspaces.annotation.pojo.SpaceClass; import com.gigaspaces.annotation.pojo.SpaceId; import com.gigaspaces.annotation.pojo.SpaceProperty; import com.gigaspaces.annotation.pojo.SpaceProperty.IndexType; import com.j_spaces.core.client.ClientUIDHandler; import com.j_spaces.core.client.ExternalEntry; @SpaceClass public class Parent { public Parent() { } public Parent(String id) { this.id = id; } public String childs_uid[]; transient Child childs[]; public Long field; public String id; public String _getChildsDetails(GigaSpace space) throws RemoteException, TransactionException, UnusableEntryException { String ret=""; Child[] childs = _getChilds(space); for (int i=0;i<childs.length ; i++) { ret = ret + childs[i].toString() + " | "; } return ret; } public Child[] _getChilds(GigaSpace space) throws RemoteException, TransactionException, UnusableEntryException { if (childs == null) { String ChildClassName = Child.class.getName(); for (int i=0;i<childs_uid.length;i++) { childs_uid[i] = ClientUIDHandler.createUIDFromName(childs_uid[i] ,ChildClassName ); } ExternalEntry templateUIDs = new ExternalEntry (childs_uid); Object results[] = space.readMultiple(templateUIDs , Integer.MAX_VALUE); childs = new Child[results.length]; for (int i=0;i<results.length ; i++) { childs [i] =(Child) ((ExternalEntry) results[i]).getObject(space.getSpace()); } } return childs; } public String _getChildUID() { String res =""; for (int i=0 ; i< childs_uid.length; i++) { res =res +childs_uid[i] + "\n"; } return res; } @SpaceProperty(index=IndexType.BASIC) public Long getField() { return field; } public void setField(Long field) { this.field = field; } public String[] getChilds_uid() { return childs_uid; } public void setChilds_uid(String[] childs_uid) { this.childs_uid = childs_uid; } @SpaceId(autoGenerate=false) public String getId() { return id; } public void setId(String id) { this.id = id; } } Application:
Application
package com.j_spaces.examples.parentchild; import java.rmi.RemoteException; import java.util.HashSet; import java.util.Set; import org.openspaces.core.GigaSpace; import org.openspaces.core.GigaSpaceConfigurer; import org.openspaces.core.space.UrlSpaceConfigurer; import net.jini.core.entry.UnusableEntryException; import net.jini.core.transaction.TransactionException; import com.j_spaces.core.client.ClientUIDHandler; import com.j_spaces.core.client.ExternalEntry; public class ParentChildMain { static GigaSpace space; static int max_graphs = 1000; static int matching_graphs = 5; public static void main(String[] args) { try { UrlSpaceConfigurer urlSpaceConfigurer = new UrlSpaceConfigurer("/./mySpace"); space = new GigaSpaceConfigurer(urlSpaceConfigurer.space()).gigaSpace(); space.clean(); System.out.println("Write " + max_graphs+ " parent/child graphs.\nWe will have 2 types of graphs:" + "\n" + matching_graphs+" graphs that got the following values for the child objects:0,1,2,3,4,5,6,7,8,9" + "\nand another " +(max_graphs - matching_graphs) + " graphs with the following values for the child objects:0,10,20,30,40,50,60,70,80,90"); go(); space.clean(); go(); space.clean(); go(); space.clean(); go(); } catch (Exception e) { e.printStackTrace(); } } static public void go() throws Exception { for (int i = 0; i < max_graphs; i++) { Parent parent = new Parent(i +""); Child childs[] = new Child[10]; parent.childs_uid = new String[10]; for (int j = 0; j < 10; j++) { childs[j] = new Child(i + "_" + j, parent.getId()); if (i% (max_graphs/matching_graphs) ==0) childs[j].field = new Long(j); else childs[j].field = new Long(j * 10); parent.childs_uid[j] = childs[j].getId(); } space.write(parent); space.writeMultiple(childs); } System.out.println("Lets find all the parent object that got 2 child object with values 1 and 2 - effectively join"); System.out.println("We need to make sure that both child objects have the same parent object"); Long startTime = System.nanoTime(); Object childs_results1[] = getChildsbyValue(new Long(1)); Set set1 = getParentUIDsSet(childs_results1); Object childs_results2[] = getChildsbyValue(new Long(2)); Set set2 = getParentUIDsSet(childs_results2); Set resultSet = AND(set1 , set2); Parent parents[] = getParentsfromUIDs(resultSet); Long endTime = System.nanoTime(); System.out.println("-----------------------------------------------------------------"); System.out.println(" --->> Found " + parents.length +" matching Parent objects in " + (double)(((double)endTime - (double)startTime)/1000000) + " ms"); for (int i = 0; i < parents.length; i++) { System.out.println("Found Parent Object:" + parents[i] + " - ID:" + parents[i].getId() + " - His children objects are:\n" + parents[i]._getChildsDetails(space)); } } static public Object[] getChildsbyValue(Long value) throws RemoteException, TransactionException, UnusableEntryException { Child child_template = new Child(); child_template.field = value; return space.readMultiple(child_template, Integer.MAX_VALUE); } static public Set getParentUIDsSet(Object entries[]) { HashSet result = new HashSet(); for (int i = 0; i < entries.length; i++) { result.add(((Child) entries[i]).parentUID); } return result; } static public Parent[] getParentsfromUIDs(Set uids) throws UnusableEntryException, RemoteException, TransactionException { Parent[] ret = null; String uids_str[] = new String [uids.size()]; System.arraycopy(uids.toArray(),0,uids_str,0,uids_str.length); String parentClassName = Parent.class.getName(); for (int i=0;i<uids_str.length;i++) { uids_str[i] = ClientUIDHandler.createUIDFromName(uids_str[i] , parentClassName ); } ExternalEntry child_uids_template = new ExternalEntry(uids_str); Object parent_results[] = space.readMultiple(child_uids_template,Integer.MAX_VALUE); ret = new Parent[parent_results.length]; for (int i=0;i<parent_results.length ; i++) { ret[i] = (Parent) ((ExternalEntry)parent_results[i]).getObject(space.getSpace()); } return ret; } // find intersection between 2 sets with IDs static public Set AND(Set set1, Set set2) { HashSet result = new HashSet(set1); result.retainAll(set2); return result; } } Expected output: Write 1000 parent/child graphs. We have 2 types of graphs: 5 graphs that have the following values for the child objects:0,1,2,3,4,5,6,7,8,9 and another 995 graphs with the following values for the child objects:0,10,20,30,40,50,60,70,80,90 Lets find all the parent objects that have 2 child objects with values 1 and 2 - effectively a join operation using ID operations. We need to make sure that both child objects have the same parent object. ----------------------------------------------------------------- --->> Found 5 matching Parent objects in 0.8 ms Found Parent Object:com.j_spaces.examples.parentchild.Parent@1b5c22f - ID:200 - His children objects are: ID:200_0 data:0 | ID:200_1 data:1 | ID:200_2 data:2 | ID:200_3 data:3 | ID:200_4 data:4 | ID:200_5 data:5 | ID:200_6 data:6 | ID:200_7 data:7 | ID:200_8 data:8 | ID:200_9 data:9 | Found Parent Object:com.j_spaces.examples.parentchild.Parent@1dfd90f - ID:800 - His children objects are: ID:800_0 data:0 | ID:800_1 data:1 | ID:800_2 data:2 | ID:800_3 data:3 | ID:800_4 data:4 | ID:800_5 data:5 | ID:800_6 data:6 | ID:800_7 data:7 | ID:800_8 data:8 | ID:800_9 data:9 | Found Parent Object:com.j_spaces.examples.parentchild.Parent@1238785 - ID:0 - His children objects are: ID:0_0 data:0 | ID:0_1 data:1 | ID:0_2 data:2 | ID:0_3 data:3 | ID:0_4 data:4 | ID:0_5 data:5 | ID:0_6 data:6 | ID:0_7 data:7 | ID:0_8 data:8 | ID:0_9 data:9 | Found Parent Object:com.j_spaces.examples.parentchild.Parent@19646fd - ID:600 - His children objects are: ID:600_0 data:0 | ID:600_1 data:1 | ID:600_2 data:2 | ID:600_3 data:3 | ID:600_4 data:4 | ID:600_5 data:5 | ID:600_6 data:6 | ID:600_7 data:7 | ID:600_8 data:8 | ID:600_9 data:9 | Found Parent Object:com.j_spaces.examples.parentchild.Parent@10ebe18 - ID:400 - His children objects are: ID:400_0 data:0 | ID:400_1 data:1 | ID:400_2 data:2 | ID:400_3 data:3 | ID:400_4 data:4 | ID:400_5 data:5 | ID:400_6 data:6 | ID:400_7 data:7 | ID:400_8 data:8 | ID:400_9 data:9 | TroubleshootingUsing LoggingUse 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 GUIUse 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 |