---
title:  Programming Your Application to Use PdxInstances
---

<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License.  You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

A `PdxInstance` is a lightweight wrapper around the raw bytes of the PDX serialized objects kept in the cache. It provides applications with run-time access to files of a PDX serialized object. <%=vars.product_name%> provides the implementation of the `PdxInstance` class.

You can configure your cache to return a `PdxInstance` when a PDX serialized object is deserialized instead of deserializing the object to a domain class. Preventing deserialization saves both time and memory and does not require you deserialize the object to the domain class.

This configuration can be done in cache.xml by setting the attribute `read-serialized` to `true` on the &lt;pdx&gt; element, or it can be done programmatically using the `CacheFactory::setPdxReadSerialized(bool)` method.

After this preference is configured, any time a PDX object is deserialized, it is deserialized into a `PdxInstance`.

The following is a code sample of using the `setField` API of `PdxInstance` to modify fields:

``` pre
RegionPtr rptr = getHelper()->getRegion( regionNames[0] );
CacheableKeyPtr keyport = CacheableKey::create("pdxput");
CacheableKeyPtr keyport1 = CacheableKey::create("pdxput2");

PdxInstancePtr pIPtr = dynCast<PdxInstancePtr>(rptr->get(keyport));
LOG( "modifyPdxInstance get complete." );

WritablePdxInstancePtr wpiPtr( pIPtr->createWriter());

ASSERT(pIPtr != NULLPTR, "pIPtr != NULLPTR expected");   
int val = 0;
int newVal = 0;
ASSERT(pIPtr->hasField("m_int32") == true, "m_id1 = true expected");
pIPtr->getField("m_int32", val);
wpiPtr->setField("m_int32", val + 1);
rptr->put(keyport, wpiPtr);  
PdxInstancePtr newPiPtr = dynCast<PdxInstancePtr>(rptr->get(keyport));  
ASSERT(newPiPtr->hasField("m_int32") == true, "m_int32 = true expected");
newPiPtr->getField("m_int32", newVal);  
ASSERT(val + 1 == newVal, "val + 1 == newVal expected");  
ASSERT((*pIPtr.ptr() == *newPiPtr.ptr()) == false, 
       "PdxInstance should not be equal");
```

In addition to field access, `PdxInstance` also supports field modification using the `setField(fieldName)` method. The `setField` method has copy-on-write semantics. So for the modifications to be stored in the cache, the `PdxInstance` must be put into a region after `setField` has been called one or more times.


