Serializing Your Domain Object with a PdxSerializer
For a domain object that you cannot or do not want to modify, use the PdxSerializer
class to serialize and deserialize the object’s fields. You use one PdxSerializer
implementation for the entire cache, programming it for all of the domain objects that you handle in this way.
With PdxSerializer
, you leave your domain object as-is and handle the serialization and deserialization in the separate serializer. You register the serializer in your cache PDX configuration. Program the serializer to handle all of the domain objects you need.
If you write your own PdxSerializer
and you also use the ReflectionBasedAutoSerializer
, then the PdxSerializer
needs to own the ReflectionBasedAutoSerializer
and delegate to it. A Cache can only have a single PdxSerializer
instance.
Note:
The PdxSerializer
toData
and fromData
methods differ from those for PdxSerializable
. They have different parameters and results.
Procedure
In the domain classes that you wish to PDX serialize, make sure each class has a zero-arg constructor. For example:
public PortfolioPdx(){}
If you have not already implemented
PdxSerializer
for some other domain object, perform these steps:Create a new class as your cache-wide serializer and make it implement
PdxSerializer
. If you want to declare your new class in thecache.xml
file, have it also implementDeclarable
.Example:
import org.apache.geode.cache.Declarable; import org.apache.geode.pdx.PdxReader; import org.apache.geode.pdx.PdxSerializer; import org.apache.geode.pdx.PdxWriter; public class ExamplePdxSerializer implements PdxSerializer, Declarable { ...
In your cache PDX configuration, register the serializer class in the cache’s
<pdx>
<pdx-serializer>
<class-name>
attribute.Example:
// Configuration setting PDX serializer for the cache <cache> <pdx> <pdx-serializer> <class-name>com.company.ExamplePdxSerializer</class-name> </pdx-serializer> </pdx> ... </cache>
Or use the
CacheFactory.setPdxSerializer
API.Cache c = new CacheFactory .setPdxSerializer(new ExamplePdxSerializer()) .create();
Note: You cannot specify a custom
pdx-serializer
class using gfsh, however theconfigure pdx
command automatically configures the org.apache.geode.pdx.ReflectionBasedAutoSerializer class. See configure pdx.Program
PdxSerializer.toData
to recognize, cast, and handle your domain object:- Write each standard Java data field of your domain class using the
PdxWriter
write methods. - Call the
PdxWriter
markIdentityField
method for each field you want to have Geode use to identify your object. Put this after the field’s write method. Geode uses this information to compare objects for operations like distinct queries. If you do not set as least one identity field, then theequals
andhashCode
methods will use all PDX fields to compare objects and consequently, will not perform as well. It is important that the fields used by yourequals
andhashCode
implementations are the same fields that you mark as identity fields. - For a particular version of your class, you need to consistently write the same named field each time. The field names or number of fields must not change from one instance to another for the same class version.
- For best performance, do fixed width fields first and then variable length fields.
- If desired, you can check the portability of the object before serializing it by adding the
checkPortability
parameter when using thePdxWriter
writeObject
,writeObjectArray
, andwriteField
methods.
Example
toData
code:public boolean toData(Object o, PdxWriter writer) { if(!(o instanceof PortfolioPdx)) { return false; } PortfolioPdx instance = (PortfolioPdx) o; writer.writeInt("id", instance.id) //identity field .markIdentityField("id") .writeDate("creationDate", instance.creationDate) .writeString("pkid", instance.pkid) .writeObject("positions", instance.positions) .writeString("type", instance.type) .writeString("status", instance.status) .writeStringArray("names", instance.names) .writeByteArray("newVal", instance.newVal) return true; }
Program
PdxSerializer.fromData
to create an instance of your class, read your data fields from the serialized form into the object’s fields using thePdxReader
read methods, and return the created object.Provide the same names that you did in
toData
and call the read operations in the same order as you called the write operations in yourtoData
implementation.Geode provides the domain class type and
PdxReader
to thefromData
method.Example
fromData
code:public Object fromData(Class<?> clazz, PdxReader reader) { if(!clazz.equals(PortfolioPdx.class)) { return null; } PortfolioPdx instance = new PortfolioPdx(); instance.id = reader.readInt("id"); instance.creationDate = reader.readDate("creationDate"); instance.pkid = reader.readString("pkid"); instance.positions = (Map<String, PositionPdx>)reader.readObject("positions"); instance.type = reader.readString("type"); instance.status = reader.readString("status"); instance.names = reader.readStringArray("names"); instance.newVal = reader.readByteArray("newVal"); return instance; }
- Write each standard Java data field of your domain class using the
If desired, you can also enable extra validation in your use of
PdxWriter
. You can set this by setting the system propertygemfire.validatePdxWriters
to true. Note that you should only set this option if you are debugging new code as this option can decrease system performance.