GigaSpaces JavaSpaces POJO support allows you to use JavaBean classes as space domain classes, and perform space operations using these objects. POJO domain Classes should follow rules similar to the ones defined by JPA, Hibernate and other domain class frameworks.
GigaSpaces POJO:
Do not implement the net.jini.core.entry interface.
When using a POJO as a space domain class, follow these guidelines:
A POJO class must implement a default (zero argument) constructor.
A POJO class cannot implement the net.jini.core.entry interface; otherwise, it is treated differently.
A POJO class should have space class metadata decorations using annotations or a gs.xml file with relevant metadata (indexed field list, version field, FIFO mode, persistency mode, primary key (i.e. id)). If neither are provided, the defaults are presumed. (The default settings might not always match your needs.)
Getter/setter methods for fields that you want to be persisted in the space.
Non-primitive fields must implement Serializable or Externalizable. For example, if you are using a POJO class that contains a nested class.
When performing matching/queries using primitive fields (int , long , double, etc.) the nullValue annotation or null-value tag must be specified with relevant values to function correctly.
The UID can be determined using the @SpaceId annotation or the id tag.
When using POJOs, write operation using the UpdateModifiers.UPDATE_OR_WRITE mode by default. This means that when the space already includes an object with the same UID (@SpaceId with the same value), the POJO is updated, and new object is not inserted.
When using SpaceId(autoGenerate=true), the UID is stored inside the SpaceId field, causing an overhead when indexed.
TokenQuery is not supported with POJOs.
POJO space mapping files gs.xml files can be loaded from:
<CLASSPATH>\config\mapping folder, or
The same package where the class file is located using the format <<Class Name>>.gs.xml.
A null value as template is not supported. Use new Object() instead.
FIFO mode is supported only at the POJO class level. You can't specify a template with fifo=false and write an object with fifo=true. You should use a different space proxy in such cases.
A POJO class must implement the Serializable or Externalizable interface if used as a parameter for a remote call (OpenSpaces remoting).
The @Spaceid annotation or id tag must be declared when performing update operations.
To persist a POJO object using the ExternalDataSource , Mirror Service, JDBC Storage Adapter, or indexed file options, the persist decoration must have the value true.
When a space configured to use the ExternalDataSource the @Spaceid annotation or id tag auto-generate attribute should be set to false. The object must include a unique value with the SpaceId field when written into the space.
The SpaceId field can be java.lang.String type or any other type that implements the toString() method.
All net.jini.core.entry.Entry based classes meta data methods are not supported with with POJO based classes. These include: _setEntryInfo() , __getEntryInfo() , __setEntryUID() , __getEntryUID() ,_getSpaceIndexedFields(). With POJO based space domain classes meta data declared using relevant annotations or xml tags.
Batch Operations
Batch operations boost performance, since they interact with the server in one call and retrieve the result from the space with one space operation. This allows the client and server to utilize the network bandwidth in efficient manner - in some cases, up to 10 times faster compared to single based operations.
readMultiple should be handled with care since it can return a large data set (potentially all space data). This might cause an out of memory error in the space and client process. You should use the GSIterator to return the result in batches in such cases.
Destructive batch operations (take , write , update) should be performed with transactions – this allows the client to roll back the space to its initial state before the operation was started, in case of a failure.
When calling writeMultiple or updateMultiple, make sure null values are not part of the passed array.
When using writeMultiple for , you should verify that duplicated entries (with the same ID) do not appear as part of the passed array, since the identity of the object is determined based on its ID and not based on its reference. This is extremely important with an embedded space, since writeMultiple injects the ID value into the object after the write operation.
readMultiple and takeMultiple do not support timeout operations. The simple way to achieve this is by calling the read operation with the proper timeout, and if non-null values are returned, perform the batch operation.
UrlSpaceConfigurer urlSpaceConfigurer = new UrlSpaceConfigurer("jini://*/*/mySpace");
GigaSpace space = new GigaSpaceConfigurer(urlSpaceConfigurer.space())
.defaultTakeTimeout(1000)
.defaultReadTimeout(1000)
.gigaSpace();
The following writes an Employee object and reads it back using a simple template:
GigaSpace space;
Employee employee = new Employee("Last Name", newInteger(32));
employee.setFirstName("first name");
space.write(employee);
Employee template = new Employee();
Employee result = space.read(template);
Registering for Notifications
The following register for notifications:
GigaSpace space;
SimpleNotifyEventListenerContainer
notifyEventListenerContainer = new SimpleNotifyContainerConfigurer(space)
.template(new Employee())
.eventListenerAnnotation(newObject()
{
@SpaceDataEvent
public void eventHappened(Object event) {
System.out.println("onEvent called Got" + event);
}
})
.fifo(true)
.notifyWrite(true)
.notifyUpdate(true)
.notifyContainer();
Writing batch of objects
When writing batch of objects into the space these should be placed into an array to be used by the GigaSpace.writeMultiple operation. The returned array will include corresponding LeaseContext object.
GigaSpace space;
Employee emps[] = new Employee[2];
emps[0] = new Employee("Last Name A", newInteger(10));
emps[1] = new Employee("Last Name B", newInteger(20));
LeaseContext[] leaseContexts = space.writeMultiple(emps);
for (int i = 0;i<leaseContexts.length ; i++)
{
System.out.println ("Object UID " + leaseContexts[i].getUID() + " inserted into the space");
}
Reading objects using SQLQuery
The following query the space using SQL:
GigaSpace space;
String querystr = "employeeID=1 or employeeID=2";
SQLQuery query = new SQLQuery(Employee.class.getName(), querystr);
Employee results[] = space.readMultiple(query , 10000);
Constructing SQLQuery objects is a relatively expensive operation. You should not construct these with every space query operation. Instead, it is recommended to construct it once, and then use it with dynamic query options: SQLQuery.setParameters and SQLQuery.setParameter.
Clearing objects
You can use the SQLQuery with the GigaSpace.clear to remove objects from the space:
When using the SQLQuery with bigger/less than queries turn on the extended indexing.
Updating an Object
The GigaSpace.write with the UpdateModifiers.UPDATE_ONLY modifier should be used to explicitly perform an update operation. The UpdateModifiers.UPDATE_OR_WRITE is the default mode with write operations. This means that subsequent calls to the write operation with an object with identical SpaceId will result an update operation - i.e. new object will not be inserted into the space.
The GigaSpace.write has few activity modes - With each mode the return object options are different.:
Inserting or updating an existing object - The UpdateModifiers.UPDATE_OR_WRITE modifier should be used. This is the default mode.
For successful operation:
o LeaseContext - Where the LeaseContext.getObject() will return the previous version of the object.
For unsuccessful operation:
o null - if timeout occurred. This means the object is locked under another transaction.
o an Exception object is thrown. Options are:
SpaceOptimisticLockingFailureException. Thrown only when running in Optimistic Locking mode. This Exception includes the existing version id of the object within the space and the client side version id of the object. In this case you should read the object again and retry the update operation. See the Optimistic Locking for more details.
When updating an object you can specify 0 (ZERO) as the lease time. This will instruct the space to use the original lease time used when the object has been written into the space.
try
{
LeaseContext ret = space.write(employee ,/*lease*/ 0 ,/*timeout*/ 1000 , UpdateModifiers.UPDATE_ONLY);
if ( ret == null)
{
// Object is locked - unsuccessful update
}
elseif (ret.getObject() instanceof Employee)
{
// successful update
}
}
catch (EntryNotInSpaceException enise)
{
// Object not in space - unsuccessful update
}
catch (SpaceOptimisticLockingFailureException solfe)
{
// Client holds wrong version of the object - unsuccessful update. We need to read it again and issue the update call again.
}
Updating batch of Objects
The GigaSpace.updateMultiple returns array of objects which correspond to the input object array. The returned object element can be either one of:
For successful operation:
o The previous version of the object
For unsuccessful operation:
o null - if timeout occurred. This means the object is locked under another transaction.
o an Exception object, in case of an exception the options are:
For successful operation:
o null - if new object inserted (write operation)
o The previous version of the object (update operation)
Since the GigaSpace.updateMultiple in UpdateModifiers.UPDATE_OR_WRITE mode does not support timeout based updates, there is no way to identify if an updated object is already locked under a transaction - i.e. the UpdateOperationTimeoutExceptionis not returned as part of the returned array elements.
With a transactional system it is recommended to perform batch updates using the UpdateModifiers.UPDATE_ONLY modifier.
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.EXPILICT takes into account only the get methods which are declared with a @SpaceProperties annotation.
IMPLICIT
inheritIndexes
String
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:
true – class indexes only.
false – class indexes and superclass indexes.
true
Field Level Annotation – @SpaceProperty
Element
Type
Description
Default Value
index
Enum of com.gigaspaces.annotation.pojo.SpaceProperty.IndexType
Defines if this field data is indexed. Querying indexed fields speeds up read and take operations. Possible values of NONE and BASIC.
It is highly recommended to index fields used for matching/query. Without the proper indexing (regular or extended ), read/readMultiple/take/takeMultiple operations response time might be affected.
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 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.
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 from type java.lang.String.
Element
Type
Description
Default Value
autoGenerate
boolean
Specifies if the object UID 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
Specifies a get method for holding the version ID. This field should be int data type.
The @SpaceVersion must be an int data type.
Field Level Decoration - @SpacePersist
Specifies a getter method for holding the persistency mode of the object overriding the class level persist declaration. This field should be boolean data type.
If the persist class level annotation is true all objects of this class type will be persistent into the underlying data store (Mirror , ExternalDataSource , Storage Adapter , Indexed File).
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 running in partitioned mode.
Field Level Decoration - @SpaceExclude
The @SpaceExclude annotation instructs the client to ignore the fields using this annotation, to not be 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 , 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
{
privateString lastName;privateString firstName;
public Person(){}
public Person(String lastName, String firstName){this.lastName = lastName;this.firstName = firstName;}
@SpaceProperty(index=IndexType.BASIC)
publicString getFirstName(){return firstName;}
public void setFirstName(String firstName){this.firstName = firstName;}
publicString 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
{
privateInteger employeeID;
privateint versionID;
public Employee(){}
public Employee(Integer employeeID){this.employeeID = employeeID;}
public Employee(String lastName, Integer employeeID)
{
this.employeeID = employeeID;
setLastName(lastName);
}
@SpaceId
@SpaceRouting
publicInteger getEmployeeID(){return employeeID;}
public void setEmployeeID(Integer employeeID){this.employeeID = employeeID;}
publicString toString(){returnsuper.toString() + ", \temployeeID: "+ employeeID ;}
@SpaceVersion
publicint getVersionID() {return versionID;}
public void setVersionID(int versionID) {this.versionID = versionID;}
}
The space mapping configuration file gs.xml allows you to define space class metadata when using POJO class with getter or setters 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 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 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 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 fifo, 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:
version
id
routing
Below is an example for an Employee class and a Person class XML configuration file named mapping.gs.xml:
<class> – a class and the associated Java class ClassDescriptor encapsulate metadata 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 persistency mode of the object. When a space is defined as persistent, a true value for this annotation will persist objects of this type.
Indicates whether the POJO should be saved in FIFO order in the space. To enable FIFO-based notifications and take operations, this annotation should be true.
<property> - contains mapping info for a primitive-typed 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-ref> - contains the full qualified name of the specified class.
<id> - defines whether this field value is used when generating the object UID.
Attribute
Description
name
Specifies a get method that allows identification of the id element in the space.
auto-generate
Specifies if the object UID 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> - instructs to exclude the POJO field under this element and not to save it 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.
generateGsXml Utility - Generating the gs.xml File
In case 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, is located at <GigaSpaces Root>\bin.
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 generate gs.xml files.
-is Hibernate
optional
Indication if 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 or a map value.
space
-isFifo
optional
Indication if to use FIFO for all the beans.
false
-isPersist
optional
Indication if to use persistent for all the beans.
true
-is Replicate
optional
Indication if 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.
You 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.
Space UID for POJOs can be created in three different ways:
When a POJO object has no SpaceId property declared, the space generated a UID for the object.
When a POJO object has a property which is declared as SpaceId and marked as auto-generate=false, the UID is generated using the ClientUIDHandler utility class.
When a POJO object has a property which is declared as SpaceId and marked as auto-generate=true, the UID is generated by the space and placed back into the field using the relevant setter method. In this case the field must be a java.lang.String type.
Fetching POJOs from the Space
POJOs can be fetched from the space using the methods read(), readMultiple(), readIfExists(), take(), takeMultiple(), takeIfExists().
A POJO can be fetched from the space in different ways:
When a POJO has no SpaceId property declared, it will be returned without any UID. This means that update operations cannot be executed on the POJO, only the read() and write() methods can be executed.
When a POJO has a property which is declared as SpaceId and auto-generate=true and its value is null, the SpaceId field will store the UID.
When a POJO has a property which is declared as SpaceId and auto-generate=true and its value is not null, the SpaceId field will store the original value stored within the SpaceId field.
When a POJO has a property which is declared as SpaceId and auto-generate=false, the SpaceId field will store the original value stored within the SpaceId field used to generate the UID.
Example - Reading POJO using ID
With the following code example the EmployeeID field 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());
}
Example - Parent Child Relationship
In some cases, you might want to store Objects within the that include refereces to other space Objects – i.e. an object graph.
The example code below demonstrates usage of ID operations to handle relashionship between objects.
The example writes 1000 parent-child graphs into the space.
Two types of graphs exist in the example:
5 graphs with the following values for the child objects: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
955 graphs with the following values for the child objects: 0, 10, 20, 30, 40, 50, 60, 70, 80, 90.
The example demonstrates a simple approach locating all the parent objects that have two child objects with values of 1 and 2 – effectively join operation using ID operations.
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;
staticint max_graphs = 1000;
staticint matching_graphs = 5;
publicstatic 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();
} }
staticpublic 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 = newString[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 = newLong(j);
else
childs[j].field = newLong(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(newLong(1));
Set set1 = getParentUIDsSet(childs_results1);
Object childs_results2[] = getChildsbyValue(newLong(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));
}
}
staticpublicObject[] getChildsbyValue(Long value) throws RemoteException, TransactionException, UnusableEntryException {
Child child_template = new Child();
child_template.field = value;
return space.readMultiple(child_template, Integer.MAX_VALUE);
}
staticpublic Set getParentUIDsSet(Object entries[]) {
HashSet result = new HashSet();
for (int i = 0; i < entries.length; i++) {
result.add(((Child) entries[i]).parentUID);
}
return result;
}
staticpublic Parent[] getParentsfromUIDs(Set uids) throws UnusableEntryException, RemoteException, TransactionException
{
Parent[] ret = null;
String uids_str[] = newString [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
staticpublic Set AND(Set set1, Set set2) {
HashSet result = new HashSet(set1);
result.retainAll(set2);
return result;
}
}
Expected output:
Write 1000 parent/child graphs.
We will have 2 types of graphs:
5 graphs that got 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 object that got 2 child object with values 1 and 2 - effectively join
We need to make sure that both child objects have the same parent object
-----------------------------------------------------------------
Lets find all the parent object that got 2 child object with values 1 and 2 - effectively join
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 |
Troubleshooting
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 will turn 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 would look 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
Use the GS-UI space class view to examine the POJO metadata. Make sure the annotations/xml decorations has been introduces to the space correctly i.e. correct class name , field names, field types , indexes , routing field , replication mode , fifo mode etc.
GigaSpaces 6.5 Documentation Contents (Current Page in Bold)