PdxInstance (Apache Geode 1.11.0)
Date: 2019-12-20

org.apache.geode.pdx

## Interface PdxInstance

- All Superinterfaces:
    Serializable
  All Known Subinterfaces:
    WritablePdxInstance

      public interface PdxInstance
      extends Serializable

  PdxInstance provides run time access to the fields of a PDX without deserializing the PDX. Preventing deserialization saves time and memory and does not require the domain class. This interface is implemented by GemFire. The PdxInstance implementation is a light weight wrapper that simply refers to the raw bytes of the PDX that are kept in the cache. Applications can choose to access PdxInstances instead of Java objects by configuring the Cache to prefer PDX instances during deserialization. This can be done in `cache.xml` by setting the attribute `read-serialized` to true on the `pdx` element. Or it can be done programmatically using either the `setPdxReadSerialized` or `client setPdxReadSerialized` method. Once this preference is configured, then any time deserialization of a PDX is done it will deserialize into a PdxInstance.

  PdxInstances are immutable. If you want to change one call `createWriter()`.

  A PdxInstance's fields will always be those of the version it represents. So if you add a field to your domain class you can end up with a PdxInstance for version 1 (that does not have the field) and a PdxInstance for version 2. The PdxInstance for version 1 will not have the added field and the PdxInstance for version 2 will have the field. This differs from deserialization of a pdx back to a domain class. In that case if version 2 is deserializing version 1 PdxReader will return a default value for the added field even though version 1 has no knowledge of it.

  Since:
    GemFire 6.6

- - ### Method Summary

    All Methods Instance Methods Abstract Methods Default Methods
    Modifier and Type | Method and Description
    --- | ---
    `WritablePdxInstance` | `createWriter()` Creates and returns a `WritablePdxInstance` whose initial values are those of this PdxInstance.
    `boolean` | `equals(Object other)` Returns true if the given object is equals to this instance.
    `String` | `getClassName()` Return the full name of the class that this pdx instance represents.
    `Object` | `getField(String fieldName)` Reads the named field and returns its value.
    `List<String>` | `getFieldNames()` Return an unmodifiable list of the field names on this PdxInstance.
    `Object` | `getObject()` Deserializes and returns the domain object that this instance represents.
    `boolean` | `hasField(String fieldName)` Checks if the named field exists and returns the result.
    `int` | `hashCode()` Generates a hashCode based on the identity fields of this PdxInstance.
    `default boolean` | `isDeserializable()` Returns false if this instance will never be deserialized to a domain class.
    `boolean` | `isEnum()` Returns true if this instance represents an enum.
    `boolean` | `isIdentityField(String fieldName)` Checks if the named field was `marked` as an identity field.
    `String` | `toString()` Prints out all of the identity fields of this PdxInstance.

- - ### Method Detail

    - #### getClassName

          String getClassName()

      Return the full name of the class that this pdx instance represents. An empty string will be returned if no class is associated with this instance.
      Returns:
        the name of the class that this pdx instance represents.
      Since:
        GemFire 6.6.2

    - #### isEnum

          boolean isEnum()

      Returns true if this instance represents an enum. Enum's have a String field named "name" and an int field named "ordinal". It is ok to cast a PdxInstance that represents an enum to `Comparable`. PdxInstances representing enums are not writable.
      Returns:
        true if this instance represents an enum.

    - #### getObject

          Object getObject()

      Deserializes and returns the domain object that this instance represents. If this instance is one that never deserializes then getObject returns "this".
      Returns:
        the deserialized domain object or "this" if this instance never deserializes
      Throws:
        `PdxSerializationException` - if the instance could not be deserialized

    - #### hasField

          boolean hasField(String fieldName)

      Checks if the named field exists and returns the result.

      This can be useful when writing code that handles more than one version of a PDX class.

      Parameters:
        `fieldName` - the name of the field to check
      Returns:
        `true` if the named field exists; otherwise `false`

    - #### getFieldNames

          List<String> getFieldNames()

      Return an unmodifiable list of the field names on this PdxInstance.
      Returns:
        an unmodifiable list of the field names on this PdxInstance

    - #### isIdentityField

          boolean isIdentityField(String fieldName)

      Checks if the named field was `marked` as an identity field.

      Note that if no fields have been marked then all the fields are used as identity fields even though this method will return `false` since none of them have been marked.

      Parameters:
        `fieldName` - the name of the field to check
      Returns:
        `true` if the named field exists and was marked as an identify field; otherwise `false`

    - #### getField

          Object getField(String fieldName)

      Reads the named field and returns its value. If the field does not exist `null` is returned.

      A `null` result indicates that the field does not exist or that it exists and its value is currently `null`. The `hasField` method can be used to figure out which if these two cases is true.

      If an Object[] is deserialized by this call then that array's component type will be `Object.class` instead of the original class that the array had when it was serialized. This is done so that PdxInstance objects can be added to the array.

      Parameters:
        `fieldName` - name of the field to read
      Returns:
        If this instance has the named field then the field's value is returned, otherwise `null` is returned.
      Throws:
        `PdxSerializationException` - if the field could not be deserialized

    - #### equals

          boolean equals(Object other)

      Returns true if the given object is equals to this instance.

      If `other` is not a PdxInstance then it is not equal to this instance. NOTE: Even if `other` is the result of calling `getObject()` it will not be equal to this instance.

      Otherwise equality of two PdxInstances is determined as follows:

      1. The domain class name must be equal for both PdxInstances
      2. Each identity field must be equal.
      If the domain class is not the empty string then if one of the instances does not have a field that the other one does then equals will assume it has the field with a default value. If a PdxInstance has marked identity fields using `markIdentityField` then only the marked identity fields are its identity fields. Otherwise all its fields are identity fields.

      An identity field is equal if all the following are true:

      1. The field name is equal.
      2. The field type is equal.
      3. The field value is equal.

      If a field's type is `OBJECT` then its value must be deserialized to determine if it is equals. If the deserialized object is an array then `deepEquals` is used to determine equality. Otherwise `equals` is used.

      If a field's type is `OBJECT[]` then its value must be deserialized and `deepEquals` is used to determine equality.

      For all other field types then the value does not need to be deserialized. Instead the serialized raw bytes are compared and used to determine equality.

      Note that any fields that have objects that do not override `equals` will cause equals to return false when you might have expected it to return true. The only exceptions to this are those that call `deepEquals` as noted above. You should either override equals and hashCode in these cases or mark other fields as your identity fields.

      Overrides:
        `equals` in class `Object`
      Parameters:
        `other` - the other instance to compare to this.
      Returns:
        `true` if this instance is equal to `other`.

    - #### hashCode

          int hashCode()

      Generates a hashCode based on the identity fields of this PdxInstance.

      If a PdxInstance has marked identity fields using `markIdentityField` then only the marked identity fields are its identity fields. Otherwise all its fields are identity fields.

      If an identity field is of type `OBJECT` then it is deserialized. If the deserialized object is an array then `deepHashCode` is used. Otherwise `hashCode` is used.

      If an identity field is of type `OBJECT[]` this it is deserialized and `deepHashCode` is used.

      Otherwise the field is not deserialized and the raw bytes of its value are used to compute the hash code.

      The algorithm used to compute the hashCode is: hashCode = 1; foreach (field: sortedIdentityFields()) { if (field.isDefaultValue()) continue; if (field.isArray()) { hashCode = hashCode*31 + Arrays.deepHashCode(field); } else { hashCode = hashCode*31 + field.hashCode(); } } if (hashCode == 0) { hashCode = 1; }

      Overrides:
        `hashCode` in class `Object`

    - #### toString

          String toString()

      Prints out all of the identity fields of this PdxInstance.

      If a PdxInstance has marked identity fields using `markIdentityField` then only the marked identity fields are its identity fields. Otherwise all its fields are identity fields.

      Overrides:
        `toString` in class `Object`

    - #### createWriter

          WritablePdxInstance createWriter()

      Creates and returns a `WritablePdxInstance` whose initial values are those of this PdxInstance. This call returns a copy of the current field values so modifications made to the returned value will not modify this PdxInstance.
      Returns:
        a `WritablePdxInstance`
      Throws:
        `IllegalStateException` - if the PdxInstance is an enum.

    - #### isDeserializable

          default boolean isDeserializable()

      Returns false if this instance will never be deserialized to a domain class. Instances that never deserialize can be created using `PdxInstanceFactory.neverDeserialize()` or by creating a factory with an empty string as the class name.
      Returns:
        false if this instance will never be deserialized to a domain class.
      Since:
        Geode 1.9