JavaSpaces POJO

  Search Here
Searching GigaSpaces XAP/EDG 6.0 Documentation

                                               

Summary: GigaSpaces JavaSpaces API Plain Old Java Object support - the POJO.

This page is specific to:
GigaSpaces 6.0

If you're interested in another version, click it below:
GigaSpaces 5.x
GigaSpaces 6.5

Overview

POJO is a Java class that does not implement the net.jini.core.entry.Entry interface.
Java classes implementing the net.jini.core.entry.Entry interface do not support annotations or gs.xml configuration when declaring their space metadata.

The Jini/JavaSpaces specification defines the Entry to be used in distributed algorithms for which exact-match lookup semantics are useful. An Entry is a typed set of objects, each of which may be tested for an exact match with a template.

A service that uses Entries supports methods that let you use Entry objects. The term "operation" is also used to describe such methods. There are three types of operations:

  • Store operations – operations that store one or more Entries, usually for future matches.
  • Match operations – operations that search for Entries that match one or more templates.
  • Fetch operations – operations that return one or more Entries.

It is possible for a single method to provide more than one of the operation types. For example, a method that returns an Entry that matches a given template can be logically split into two operation types (match and fetch). In this way, any statements made in this specification about either operation type apply to the appropriate part of the method's behavior.

An Entry is a typed group of object references represented by a class that implements the marker interface net.jini.core.entry.Entry. Two different Entries have the same type only if they are of the same class.

package net.jini.core.entry;
public interface Entry extends java.io.Serializable { }
For the purpose of the Jini/Javaspaces specification, the term "field" when applied to an Entry, will mean fields that are public, non-static, non-transient, and non-final.

Other fields of an Entry are not affected by Entry operations. In particular, when an Entry object is created and filled in by a fetch operation; only the public, non-static, non-transient, and non-final fields of the Entry are set. Other fields are not affected, except as set by the class's no-arg constructor.

Each Entry class must provide a public no-arg constructor. Entries cannot have fields of a primitive type (int, boolean, etc.), however, the objects they refer to may have primitive fields and non-public fields. When performing any type of operation, an attempt to use a malformed Entry type that has primitive fields, or does not have a no-arg constructor, throws IllegalArgumentException.

For more details on the Jini/JavaSpaces Entry, refer to: java.sun.com - EN - Jini Entry Specification

JavaSpaces API support

The GigaSpaces POJO JavaSpaces support allows you to perform JavaSpaces operations using Java objects that:

  • Do not implement the net.jini.core.entry interface.
  • Have private fields.
  • Have primitive type (int, boolean, etc.) fields.
  • Have getter and setter methods.
You can define space classes meta data by class and field level decorations. These can be defined via Annotations and XML configurations files. For more details, refer to the POJO Class and Field Level Annotations section.

The following JavaSpaces APIs have been modified to support POJOs:

  • GSIterator – the method next() returns Object instead of Entry.
  • NotifyDelegator – a constructor has been added which gets Object.
  • EntryArrivedRemoteEvent – The method getObject() has been added, which returns Object.
  • ExternalEntry – An _objectFormat member has been added, to indicate if the current ExternalEntry is holding a POJO or an Entry. (The default the members is set to Entry).
  • SQLQuery:
    • The constructor SQLQuery(Object object, String sqlQuery) has been added.
    • The methods public Object getObject(), and public void setTemplate(Object object) have been added.

The methods that were added into the IJSpace APIs to support POJO are:

  • clear():
    public void clear(Object template, Transaction txn)
  • count():
    public int count(Object template, Transaction txn);
  • The Notify Registration methods provide the support necessary for a client to be notified of the existence of an Entry. Notification can occur under a transaction as well.
    public EventRegistration notify(Object entry,
                                    Transaction transaction,
                                    RemoteEventListener listener,
                                    long leaseTime,
                                    MarshalledObject handbackObject) throws 
                                                                     TransactionException, 
                                                                     RemoteException;
    
    public EventRegistration notify(Object template,
                                    Transaction txn,
                                    RemoteEventListener listener,
                                    long leaseTime,
                                    MarshalledObject handbackObject,
                                    int modifiers ) throws 
                                                    TransactionException, 
                                                    RemoteException;
  • Single read:
    public Object read(Object entry, 
                       Transaction transaction, 
                       long timeout) throws 
                                     UnusableEntryException, 
                                     TransactionException, 
                                     InterruptedException, 
                                     RemoteException
  • readIfExists()
    public Object readIfExists(Object entry, 
                               Transaction transaction, 
                               long timeout) throws 
                                     UnusableEntryException, 
                                     TransactionException, 
                                     InterruptedException, 
                                     RemoteException
  • snapshot()
    public Object snapshot(Object entry) throwsRemoteException
  • Single take
    public Object take(Object entry, 
                       Transaction transaction, 
                       long timeout) throws 
                                     UnusableEntryException, 
                                     ransactionException, 
                                     InterruptedException, 
                                     RemoteException
  • takeIfExists():
    public Object takeIfExists(Object entry, 
                               Transaction transaction, 
                               long timeout) throws 
                                             UnusableEntryException, 
                                             TransactionException, 
                                             InterruptedException,
                                             RemoteException
  • Single update:
    public Object update(Object updatedEntry, 
                         Transaction transaction, 
                         long lease, 
                         long timeout) throws 
                                       TransactionException, 
                                       UnusableEntryException, 
                                       java.rmi.RemoteException, 
                                       InterruptedException
    
    public Object update(Object updatedEntry, 
                         Transaction transaction, 
                         long lease, 
                         long timeout, 
                         int updateModifiers) throws 
                                              TransactionException, 
                                              UnusableEntryException, 
                                              java.rmi.RemoteException, 
                                              InterruptedException
  • Write or update:
    public LeaseContext write(Object entry, 
                              Transaction transaction, 
                              long lease) throws 
                                          TransactionException, 
                                          RemoteException
    
    public LeaseContext write(Object entry, 
                              Transaction transaction, 
                              long lease, 
                              long timeout, 
                              int modifiers) throws 
                                             TransactionException, 
                                             RemoteException
  • Batch read:
    public Object[] readMultiple(Object template, 
                                 Transaction txn, 
                                 int maxEntries) throws 
                                                 TransactionException, 
                                                 UnusableEntryException, 
                                                 java.rmi.RemoteException
  • Batch write:
    Lease[] writeMultiple(Object[] entries, 
                          Transaction txn, 
                          long lease) throws 
                                      TransactionException, 
                                      java.rmi.RemoteException
  • Batch update:
    public Object[] updateMultiple(Object[] entries, 
                                   Transaction transaction, 
                                   long[] leases) throws 
                                                  UnusableEntryException, 
                                                  TransactionException, 
                                                  java.rmi.RemoteException
    
    public Object[] updateMultiple(Object[] entries, 
                                   Transaction transaction, 
                                   long[] leases, 
                                   int updateModifiers) throws 
                                                        UnusableEntryException, 
                                                        TransactionException, 
                                                        java.rmi.RemoteException
  • Batch take:
    Object[] takeMultiple(Object template, 
                          Transaction txn, 
                          int maxEntries) throws 
                                          TransactionException, 
                                          UnusableEntryException,
                                          java.rmi.RemoteException

Examples

Person Class

Person
package com.j_spaces.examples.hellospacepojo;
import com.gigaspaces.annotation.pojo.SpaceClass;
import com.gigaspaces.annotation.pojo.SpaceField;
@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)
	private String getFirstName()
	{
		return firstName;
	}

	public void setFirstName(String firstName)
	{
		this.firstName = firstName;
	}

	private String getLastName()
	{
		return lastName;
	}

	public void setLastName(String name)
	{
		this.lastName = name;
	}

	public boolean equals(Object other)
	{
		if (!(other instanceof Person))
			return false;
		else
		{
			Person otherBean = (Person) other;
			return ((otherBean.lastName != null
                   && otherBean.lastName.equals(lastName) || otherBean.lastName == lastName))
                   && ((otherBean.getFirstName() != null
                   && otherBean.getFirstName().equals(getFirstName()) || otherBean.getFirstName() 
                   == getFirstName()));
		}
	}

	public String toString()
	{
		return " \tlastName: " + lastName + ", \tfirstName: "
				+ firstName;
	}
}

Employee Class

Employee
package com.j_spaces.examples.hellospacepojo;

import com.gigaspaces.annotation.pojo.Key;
import com.gigaspaces.annotation.pojo.SpaceClass;
import com.gigaspaces.annotation.pojo.SpaceField;


@SpaceClass(replicate=true,persist=false,fifo=false)
public class Employee
	extends Person
{
	private Integer	employeeID;
	public Employee(){}
	public Employee(Integer employeeID)
	{
		this.employeeID = employeeID;
	}

	public Employee(String lastName, Integer employeeID)
	{
		this.employeeID = employeeID;
		setLastName(lastName);
	}
	
	@SpaceId
	private Integer getEmployeeID()
	{
		return employeeID;
	}

	private void setEmployeeID(Integer employeeID)
	{
		this.employeeID = employeeID;
	}


	public boolean equals(Object other)
	{
		if (!(other instanceof Employee))
			return false;
		else
		{
            Employee otherBean = (Employee) other;
            return ((otherBean.getEmployeeID() != null
            && otherBean.getEmployeeID().equals(getEmployeeID()) || otherBean.getEmployeeID() 
            == getEmployeeID()));
		}
	}

	public String toString()
	{
		return super.toString() + ", \temployeeID: "
				+ employeeID;
	}
}

Writing and Reading POJOs

The following writes an Employee object, and reads it back using a template:

IJSpace space = (IJSpace) SpaceFinder.find(args[0]);
Employee employee = new Employee("Last Name", new Integer(32));
employee.setFirstName("first name");
space.write(employee, null, Lease.FOREVER);
Employee templatePojo = new Employee();
Employee result = (Employee) space.read(templatePojo,null,Long.MAX_VALUE);

Registering for Notifications

The notify registration:

session.addListener(templatePojo,new HelloWorldPOJONotifyDelegator(),Lease.FOREVER,
                               null,null, NotifyActionType.NOTIFY_ALL);

The listener:

public class HelloWorldPOJONotifyDelegator
		implements RemoteEventListener
{
	public void notify(RemoteEvent theEvent) throws UnknownEventException,
			RemoteException
	{
		try
		{
			// since we are using NotifyDelegator, we can obtain the entry
			// that triggered the event
			EntryArrivedRemoteEvent arrivedRemoteEvent = (EntryArrivedRemoteEvent) theEvent;
			Employee backToPojo = (Employee) arrivedRemoteEvent.getObject();
			int notifyType = arrivedRemoteEvent.getNotifyType();
			String msgStr = "NOTIFY- Type:" + getNotifyDesc(notifyType) + "; "
					+ "Event-Sequence#: " + theEvent.getSequenceNumber() + "; "
					+ "Content: '" + backToPojo + "';";

			System.out.println(msgStr);
		}
		catch (Exception ex)
		{
			ex.printStackTrace();
		}
	}

	private String getNotifyDesc(int notifyType)
	{
		String desc = "";
		if (NotifyModifiers.isWrite(notifyType))
			desc = "Write";
		if (NotifyModifiers.isTake(notifyType))
			desc = "Take";
		if (NotifyModifiers.isLeaseExpiration(notifyType))
			desc = "LeaseExpiration";
		if (NotifyModifiers.isUpdate(notifyType))
			desc = "Update";
		if (NotifyModifiers.isALL(notifyType))
			desc = "ALL";
		return desc;
	}

}

Transactions

LocalTransactionManager trManager = (LocalTransactionManager) LocalTransactionManager.
getInstance((IJSpace) space);
Transaction.Created tCreated = TransactionFactory.create(	trManager,
Transaction txn = tCreated.transaction;
Employee employee = new Employee("Last Name", new Integer(32));
space.write(employee, txn, Lease.FOREVER);
txn.commit(10000);

SQLQuery

String querystr	= "employeeID=1 or employeeID=2";
SQLQuery query = new SQLQuery(Employee.class.getName(), querystr);
Object result1[] = (Object[]) space.readMultiple((Object)query,null,Integer.MAX_VALUE);
When using SQLQuery with POJOs, you should cast the SQLQuery template to java.lang.Object, when using it as an argument as part of the readMultiple operation.

POJO UID Generation and Usage Scenarios

Inserting POJOs into the Space

You can insert POJOs into the space using the write() and writeMultiple() methods.

Space UID for POJOs can be created in three different ways:

  • When a POJO object has no Space Id property declared, the ExternalEntry is created with an empty UID. The space gets the ExternalEntry which was created and inserts it into the space. The space then generates a UID for that ExternalEntry instance and writes it into the space.
  • When a POJO object has a property which is declared as Space Id, the converter takes the value of that property and calls the method getUID(Object name) from the ClientUIDHandler class. This method returns a UID which is generated using the property value. The UID is set to the ExternalEntry object.
  • When a POJO object has a property which is declared as Space Id and marked as auto-generate, the property must be of type java.lang.String. The ExternalEntry is created with an empty UID. The space gets the ExternalEntry which was created and inserts it into the space. The space then generates a UID for that ExternalEntry instance and writes it into the space. The generated UID is then set into the POJO instance using a set property method.

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 three different ways:

  • When a POJO has no Space Id property declared, it will be returned without any UID. This means that only the read() and write() methods, and not an update() method, can be executed on the POJO.
  • When a POJO has a Space Id property declared, it will be returned with the source value of the property, but without the generated UID. The POJO can not approach the UID which was generated by the space.
  • When a POJO has a property which is declared as Space Id and auto generate, the space returns the POJO with the generated UID into the property.

Considerations, Known Issues and Limitations

  • When using POJOs, write without the UpdateModifier uses UPDATE_OR_WRITE, ignoring the proxy modifier.
  • UIDs with autoGenerate=true – the UID is stored inside the Space Id field, causing an overhead when indexed.
  • Only Native Serialization mode is supported.
  • POJO operations are relatively slower than Entry operations, especially in Embedded.
  • TokenQuery is not supported.
  • POJO space mapping files – gs.xml files – can be loaded either from the <GigaSpaces Root>/config/mapping folder, or from the same package as the introduced class using the format ClassName.gs.xml.
  • No null value as template support (use new Object() instead).
  • The FIFO and persistent annotations or the space mapping element file are supported only in the POJO's class level.
  • Batch operations (ReadMultiple, takeMutiple) return an array of POJO instances, when the template used is ExternalEntry and its ObjectFormat type is POJO.


GigaSpaces 6.0 Documentation Contents (Current Page in Bold)

    Java

    C++

    .NET

    Middleware Capabilities

    Configuration and Management

Add GigaSpaces wiki search to your browser search engines!
(works on Firefox 2 and Internet Explorer 7)

Labels