org.apache.ignite.internal.portable.api

## Interface PortableObject

All Superinterfaces:
  Cloneable, Serializable

All Known Implementing Classes:
  PortableObjectEx, PortableObjectImpl, PortableObjectOffheapImpl

    public interface PortableObject
    extends Serializable, Cloneable

Wrapper for portable object in portable binary format. Once an object is defined as portable, Ignite will always store it in memory in the portable (i.e. binary) format. User can choose to work either with the portable format or with the deserialized form (assuming that class definitions are present in the classpath).

NOTE: user does not need to (and should not) implement this interface directly.

To work with the portable format directly, user should create a cache projection over `PortableObject` class and then retrieve individual fields as needed:

     IgniteCache<PortableObject, PortableObject> prj = cache.withKeepPortable();

     // Convert instance of MyKey to portable format.
     // We could also use GridPortableBuilder to create the key in portable format directly.
     PortableObject key = grid.portables().toPortable(new MyKey());

     PortableObject val = prj.get(key);

     String field = val.field("myFieldName");

Alternatively, if we have class definitions in the classpath, we may choose to work with deserialized typed objects at all times. In this case we do incur the deserialization cost. However, if `PortableMarshaller.isKeepDeserialized()` is `true` then Ignite will only deserialize on the first access and will cache the deserialized object, so it does not have to be deserialized again:

     IgniteCache<MyKey.class, MyValue.class> cache = grid.cache(null);

     MyValue val = cache.get(new MyKey());

     // Normal java getter.
     String fieldVal = val.getMyFieldName();

# Working With Maps and Collections

All maps and collections in the portable objects are serialized automatically. When working with different platforms, e.g. C++ or .NET, Ignite will automatically pick the most adequate collection or map in either language. For example, `ArrayList` in Java will become `List` in C#, `LinkedList` in Java is `LinkedList` in C#, `HashMap` in Java is `Dictionary` in C#, and `TreeMap` in Java becomes `SortedDictionary` in C#, etc.

# Dynamic Structure Changes

Since objects are always cached in the portable binary format, server does not need to be aware of the class definitions. Moreover, if class definitions are not present or not used on the server, then clients can continuously change the structure of the portable objects without having to restart the cluster. For example, if one client stores a certain class with fields A and B, and another client stores the same class with fields B and C, then the server-side portable object will have the fields A, B, and C. As the structure of a portable object changes, the new fields become available for SQL queries automatically.

# Building Portable Objects

Ignite comes with `PortableBuilder` which allows to build portable objects dynamically:

     PortableBuilder builder = Ignition.ignite().portables().builder("org.project.MyObject");

     builder.setField("fieldA", "A");
     builder.setField("fieldB", "B");

     PortableObject portableObj = builder.build();

For the cases when class definition is present in the class path, it is also possible to populate a standard POJO and then convert it to portable format, like so:

     MyObject obj = new MyObject();

     obj.setFieldA("A");
     obj.setFieldB(123);

     PortableObject portableObj = Ignition.ignite().portables().toPortable(obj);

# Portable Metadata

Even though Ignite portable protocol only works with hash codes for type and field names to achieve better performance, Ignite provides metadata for all portable types which can be queried ar runtime via any of the `IgnitePortables.metadata(Class)` methods. Having metadata also allows for proper formatting of `PortableObject.toString()` method, even when portable objects are kept in binary format only, which may be necessary for audit reasons.

### Method Summary

Methods
`PortableObject` `clone()` Copies this portable object.
`<T> T` `deserialize()` Gets fully deserialized instance of portable object.
`<F> F` `field(String fieldName)` Gets field value.
`boolean` `hasField(String fieldName)` Checks whether field is set.
`PortableMetadata` `metaData()` Gets meta data for this portable object.
`int` `typeId()` Gets portable object type ID.

### Method Detail

#### typeId

    int typeId()

Gets portable object type ID.

Returns:
  Type ID.

#### metaData

    @Nullable
    PortableMetadata metaData()
                              throws PortableException

Gets meta data for this portable object.

Returns:
  Meta data.
Throws:
  `PortableException` - In case of error.

#### field

    @Nullable
    <F> F field(String fieldName)
            throws PortableException

Gets field value.

Parameters:
  `fieldName` - Field name.
Returns:
  Field value.
Throws:
  `PortableException` - In case of any other error.

#### hasField

    boolean hasField(String fieldName)

Checks whether field is set.

Parameters:
  `fieldName` - Field name.
Returns:
  `true` if field is set.

#### deserialize

    @Nullable
    <T> T deserialize()
                  throws PortableException

Gets fully deserialized instance of portable object.

Returns:
  Fully deserialized instance of portable object.
Throws:
  `PortableInvalidClassException` - If class doesn't exist.
  `PortableException` - In case of any other error.

#### clone

    PortableObject clone()
                         throws CloneNotSupportedException

Copies this portable object.

Returns:
  Copy of this portable object.
Throws:
  `CloneNotSupportedException`

2015 Copyright © Apache Software Foundation

Follow @ApacheIgnite

Ignite Fabric | : ver. 1.4.0
Release Date | : September 24 2015