XAP.NET 9.1 Documentation > Back to Table of Contents
How to Codify ID Based Parent-Child Relationships
Summary: This article demonstrates how to build a program which supports Parent-Child Relationships with the GigaSpaces Data-Grid. The program allows for returning Child objects through methods invoked by the Parent. The application also demonstrates how to return a parent object through the child
OverviewThe program below demonstrates how to build and implement Parent-Child relationships. In this example, the Parent object stores a reference to the Child object or objects within its class, rather than the Child object itself.
When the Parent object stores a reference to the Child object, you may want to fetch the parent object that is associated with a child object. The example below demonstrates how ID operations handle relationships between objects. This example uses the ReadByIds batch operation to retrieve multiple space objects using on their ID: IReadByIdsResult<Child> childrenObjResult = space.ReadByIds(Child.class,childrenIDs); The application first writes 10000 parent-child graphs into the space. The write function creates two types of graphs:
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.SpaceIndex; import com.gigaspaces.annotation.pojo.SpaceRouting; import com.gigaspaces.metadata.index.SpaceIndexType; //This is the child class object. Its ID will be stored in the Parent object. The Child class stores its parent id to create a dual //connection between the two classes. [SpaceClass] public class Child { private string _parentID; private long _data; private string _id; public Child() { } public Child(String id, String parentID) { this._parentID = parentID; this._id = id; } public string ToString() { return "ID:" + _id + " data:" + _data; } [SpaceProperty(NullValue = 0)] [SpaceIndex(type = SpaceIndexType.BASIC)] public long data { get { return _data; } set { _data = value; } } [SpaceId(autoGenerate = false)] public string id { get { return _id; } set { _id = value; } } [SpaceIndex(type = SpaceIndexType.BASIC)] [SpaceRouting] public string parentID { get { return this._parentID; } set { this._parentID = value; } } } 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.SpaceIndex; import com.gigaspaces.annotation.pojo.SpaceRouting; import com.gigaspaces.client.ReadByIdsResult; import com.gigaspaces.metadata.index.SpaceIndexType; //The parent class, which holds a string array, each entry referring to a different child ID. The Class also holds a copy of the //Child object, however this is for temporary use only and the Child object stored in the _children_ field is not stored in the //actual memory. [SpaceClass] public class Parent { private string [] _childrenIDs; private Child [] _children; private long _data; private string _id; static string ChildClassName = Child.class.getName(); public Parent() { } public Parent(string id) { this._id = id; } public string GetChildrenDetails(ISpaceProxy space) { String ret=""; Child[] childs = GetChildren(space); for (int i=0;i<childs.Length ; i++) { ret = ret + childs[i].ToString() + " | "; } return ret; } public Child[] GetChildren(ISpaceProxy space) { if (_children == null) { IReadByIdsResult<Child> childrenObjResult = space.ReadByIds(Child, _childrenIDs); _children = childrenObjResult.ResultsArray; } return _children; } public String GetChildrenIDs() { String res =""; for (int i=0 ; i< _childrenIDs.Length; i++) { res =res + _childrenIDs[i] + "\n"; } return res; } [SpaceIndex(type=SpaceIndexType.BASIC)] public long Data { get { return _data; } set { _data = value; } } public string[] ChildrenIDs { get { return _childrenIDs; } set { _childrenIDs = value; } } [SpaceId(autoGenerate=false)] [SpaceRouting] public string Id { get { return _id; } set { _id = value; } } } } 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.gigaspaces.client.ReadByIdsResult; public class ParentChildMain { static ISpaceProxy Space; static int Max_graphs = 10000; static int Matching_graphs = 5; public static void main(String[] args) { try { //Initalize the space object Space = GigaSpacesFactory.FindSpace("/./mySpace"); Console.WriteLine("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(); } catch (Exception e) { Console.WriteLine(e.Message); } } static public void go() { for (int i = 0; i < Max_graphs; i++) { //Create the parent objects Parent parent = new Parent(i +""); //Create array of Child objects to be associated with the Parent object Child [] children = new Child[10]; string [] childrenIDs = new String[10]; for (int j = 0; j < 10; j++) { //assign data to the child object children[j] = new Child(i + "_" + j, parent.Id); if (i% (Max_graphs/Matching_graphs) ==0) children[j].data = j; else children[j].data = j * 10; childrenIDs[j] = children[j].id; } //save the child ID values in the parent object parent.ChildrenIDs = childrenIDs; //Save the parent object to the Space Space.Write(parent); //Save the Child array object to the Space Space.WriteMultiple(children); } FindMatchingGraph(1,2); FindMatchingGraph(3,4); FindMatchingGraph(5,6); FindMatchingGraph(7,8); } static void FindMatchingGraph(long value1, long value2) { Console.WriteLine("-----------------------------------------------------------------"); Console.WriteLine("Find all the parent objects that have 2 child objects with values: " + value1 +" and " + value2+ ""); Console.WriteLine("Both child objects have the same parent object"); DateTime startTime = System.DateTime.Now; Object [] childrenResults1 = FindChildrenByValue(new long(value1)); Set<String> parentIDs1 = GetParentIDsSet(childrenResults1); Object [] childrenResults2 = FindChildrenByValue(new Long(value2)); Set<String> parentIDs2 = GetParentIDsSet(childrenResults2); Set<String> resultSet = AND(parentIDs1, parentIDs2); Parent [] parents = GetParentsfromIDs(resultSet); DateTime endTime = System.DateTime.Now; Console.WriteLine(" --->> Found " + parents.Length + " matching Parent objects in " + (double)(((double)endTime - (double)startTime)/1000) + " micro second"); for (int i = 0; i < parents.Length; i++) { Console.WriteLine("Found Parent Object:" + parents[i] + " - ID:" + parents[i].Id + " - Children objects:\n\t" + parents[i].GetChildrenDetails(Space)); } } static public Object[] FindChildrenByValue(long value) { Child childTemplate = new Child(); childTemplate.data = value; return Space.ReadMultiple(childTemplate , int.MaxValue); } static public Set<String> GetParentIDsSet(Object [] entries) { HashSet<String> result = new HashSet<String>(); for (int i = 0; i < entries.Length; i++) { result.Add(((Child) entries[i]).parentID)); } return result; } static public Parent[] GetParentsfromIDs(Set ids) { IReadByIdsResult<Parent> parentObjResult = Space.ReadByIds(Parent.class, ids.toArray()); return parentObjResult.getResultsArray(); } // find union between set1 and set2 static public Set<String> AND(Set<String> set1, Set<String> set2) { HashSet<String> result = new HashSet<String>(set1); result.retainAll(set2); return result; } } } Expected outputWrite 10000 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 9995 graphs with the following values for the child objects:0,10,20,30,40,50,60,70,80,90 ----------------------------------------------------------------- Find all the parent objects that got 2 child objects with values 1 and 2 Both child objects have the same parent object --->> Found 5 matching Parent objects in 623.38 micro second Found Parent Object:com.j_spaces.examples.parentchild.Parent@335053 - ID:8000 - Children objects: ID:8000_0 data:0 | ID:8000_1 data:1 | ID:8000_2 data:2 | .... Found Parent Object:com.j_spaces.examples.parentchild.Parent@1c0cd80 - ID:0 - Children objects: ID:0_0 data:0 | ID:0_1 data:1 | ID:0_2 data:2 | ... Found Parent Object:com.j_spaces.examples.parentchild.Parent@f3c5c4 - ID:6000 - Children objects: ID:6000_0 data:0 | ID:6000_1 data:1 | ID:6000_2 data:2 | ... Found Parent Object:com.j_spaces.examples.parentchild.Parent@3ce725 - ID:4000 - Children objects: ID:4000_0 data:0 | ID:4000_1 data:1 | ID:4000_2 data:2 | ... Found Parent Object:com.j_spaces.examples.parentchild.Parent@6b6ac8 - ID:2000 - Children objects: ID:2000_0 data:0 | ID:2000_1 data:1 | ID:2000_2 data:2 | ... |
![]() |
GigaSpaces.com - Legal Notice - 3rd Party Licenses - Site Map - API Docs - Forum - Downloads - Blog - White Papers - Contact Tech Writing - Gen. by Atlassian Confluence |