blob: 0ed38fc08f44f35e2cfe44b14e9bbf7298ac7044 [file] [log] [blame]
---
title: Using Automatic Reflection-Based PDX Serialization
---
<!--
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.
-->
You can configure your cache to automatically serialize and deserialize domain objects without having to add any extra code to them.
<a id="auto_serialization__section_E2B7719D3C1545808CC21E0FDBD2D610"></a>
You can automatically serialize and deserialize domain objects without coding a `PdxSerializer` class. You do this by registering your domain objects with a custom `PdxSerializer` called `ReflectionBasedAutoSerializer` that uses Java reflection to infer which fields to serialize.
You can also extend the ReflectionBasedAutoSerializer to customize its behavior. For example, you could add optimized serialization support for BigInteger and BigDecimal types. See [Extending the ReflectionBasedAutoSerializer](extending_the_autoserializer.html#concept_9E020566EE794A81A48A90BA798EC279) for details.
**Note:**
Your custom PDX autoserializable classes cannot use the `org.apache.geode` package. If they do, the classes will be ignored by the PDX auto serializer.
<a id="auto_serialization__section_C69046B44729454F8CD464B0289EFDD8"></a>
**Prerequisites**
- Understand generally how to configure the <%=vars.product_name%> cache.
- Understand how PDX serialization works and how to configure your application to use `PdxSerializer`.
<a id="auto_serialization__section_43F6E45FF69E470897FD9D002FBE896D"><strong>Procedure</strong></a>
In your application where you manage data from the cache, provide the following configuration and code as appropriate:
1. In the domain classes that you wish to autoserialize, make sure each class has a zero-arg constructor. For example:
``` pre
public PortfolioPdx(){}
```
2. Using one of the following methods, set the PDX serializer to `ReflectionBasedAutoSerializer`.
1. In gfsh, execute the following command prior to starting up any members that host data:
``` pre
gfsh>configure pdx --auto-serializable-classes=com\.company\.domain\..*
```
By using gfsh, this configuration can propagated across the cluster through the [Cluster Configuration Service](../../configuring/cluster_config/gfsh_persist.html).
2. Alternately, in `cache.xml`:
``` pre
<!-- Cache configuration configuring auto serialization behavior -->
<cache>
<pdx>
<pdx-serializer>
<class-name>
org.apache.geode.pdx.ReflectionBasedAutoSerializer
</class-name>
<parameter name="classes">
<string>com.company.domain.DomainObject</string>
</parameter>
</pdx-serializer>
</pdx>
...
</cache>
```
The parameter, `classes`, takes a comma-separated list of class patterns to define the domain classes to serialize. If your domain object is an aggregation of other domain classes, you need to register the domain object and each of those domain classes explicitly for the domain object to be serialized completely.
3. Using the Java API:
``` pre
Cache c = new CacheFactory()
.setPdxSerializer(new ReflectionBasedAutoSerializer("com.company.domain.DomainObject"))
.create();
```
3. Customize the behavior of the `ReflectionBasedAutoSerializer` using one of the following mechanisms:
- By using a class pattern string to specify the classes to auto-serialize and customize how the classes are serialized. Class pattern strings can be specified in the API by passing strings to the `ReflectionBasedAutoSerializer` constructor or by specifying them in cache.xml. See [Customizing Serialization with Class Pattern Strings](autoserialization_with_class_pattern_strings.html#concept_9B67BBE94B414B7EA63BD7E8D61D0312) for details.
- By creating a subclass of `ReflectionBasedAutoSerializer` and overriding specific methods. See [Extending the ReflectionBasedAutoSerializer](extending_the_autoserializer.html#concept_9E020566EE794A81A48A90BA798EC279) for details.
4. If desired, configure the `ReflectionBasedAutoSerializer` to check the portability of the objects it is passed before it tries to autoserialize them. When this flag is set to true, the `ReflectionBasedAutoSerializer` will throw a `NonPortableClassException` error when trying to autoserialize a non-portable object. To set this, use the following configuration:
- In gfsh, use the following command:
``` pre
gfsh>configure pdx --portable-auto-serializable-classes=com\.company\.domain\..*
```
By using gfsh, this configuration can propagated across the cluster through the [Cluster Configuration Service](../../configuring/cluster_config/gfsh_persist.html).
- In cache.xml:
``` pre
<!-- Cache configuration configuring auto serialization behavior -->
<cache>
<pdx>
<pdx-serializer>
<class-name>
org.apache.geode.pdx.ReflectionBasedAutoSerializer
</class-name>
<parameter name="classes">
<string>com.company.domain.DomainObject</string>
</parameter>
<parameter name="check-portability">
<string>true</string>
</parameter>
</pdx-serializer>
</pdx>
...
</cache>
```
- Using the Java API:
``` pre
Cache c = new CacheFactory()
.setPdxSerializer(new ReflectionBasedAutoSerializer(true,"com.company.domain.DomainObject"))
.create();
```
For each domain class you provide, all fields are considered for serialization except those defined as `static` or `transient` and those you explicitly exclude using the class pattern strings.
**Note:**
The `ReflectionBasedAutoSerializer` traverses the given domain object's class hierarchy to retrieve all fields to be considered for serialization. So if `DomainObjectB` inherits from `DomainObjectA`, you only need to register `DomainObjectB` to have all of `DomainObjectB` serialized.