Serialization is the process of encoding an object into a binary format. It is a critical component when working with Coherence as data must be moved around the network. The Portable Object Format (also referred to as POF) is a language agnostic binary format. POF was designed to be incredibly efficient in both space and time and has become a cornerstone element in working with Coherence. Using POF has many advantages ranging from performance benefits to language independence. It's recommended that you look closely at POF as your serialization solution when working with Coherence.
This chapter focuses only on the changes and additions that you need to make to your TopLink application files to make them eligible to participate in POF serialization. For more detailed information on using and configuring POF, see "Using Portable Object Format" in the Developers Guide for Oracle Coherence.
This chapter contains the following sections:
You must implement serialization routines that know how to serialize and deserialize your Entities. You can do this by implementing the PortableObject
interface or by creating a serializer using the com.tangosol.io.pof.PofSerializer
interface.
Implement the PortableObject
interface in your Entity class files
The com.tangosol.io.pof.PortableObject
interface provides classes with the ability to self-serialize and deserialize their state to and from a POF data stream. To use this interface, you must also provide implementations of the required methods readExternal
and writeExternal
.
Example 4-1 illustrates a sample Entity class file that implements the PortableObject
interface. Note the implementations of the required readExternal
and writeExternal
methods.
Also note that the class includes an @OneToOne
annotation to define the relationship mapping between the Trade
object and a Security
object. TopLink supports all of the relationship mappings defined by the JPA specification: one-to-one, one-to-many, many-to-many, and many-to-many. These relationships can be expressed as annotations. Do not serialize or deserialize relationship mappings; TopLink Grid will perform these operations automatically.
Example 4-1 Sample Entity Class that Implements PortableObject
package oracle.toplinkgrid.codesample.pof.models.trader; import java.io.IOException; import java.io.Serializable; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToOne; import com.tangosol.io.pof.PofReader; import com.tangosol.io.pof.PofWriter; import com.tangosol.io.pof.PortableObject; /** * This class will not be stored within Coherence as Trades are not high * throughput objects in this model. * */ @Entity public class Trade implements Serializable, PortableObject{ /** * */ private static final long serialVersionUID = -244532585419336780L; @Id @GeneratedValue protected long id; @OneToOne(fetch=FetchType.EAGER) protected Security security; protected int quantity; protected double amount; public long getId() { return id; } public void setId(long id) { this.id = id; } public Security getSecurity() { return security; } public void setSecurity(Security security) { this.security = security; } public int getQuantity() { return quantity; } public void setQuantity(int quantity) { this.quantity = quantity; } public double getAmount() { return amount; } public void setAmount(double amount) { this.amount = amount; } public void readExternal(PofReader pofreader) throws IOException { id = pofreader.readLong(0); quantity = pofreader.readInt(2); amount = pofreader.readDouble(3); } public void writeExternal(PofWriter pofwriter) throws IOException { pofwriter.writeLong(0, id); pofwriter.writeInt(2, quantity); pofwriter.writeDouble(3, amount); } }
Create a POFSerializer
for the Entities
An alternative to implementing the PortableObject
interface is to implement the com.tangosol.io.pof.PofSerializer
interface to create your own serializer and deserializer. This interface provides you with a way to externalize your serialization logic from the Entities you want to serialize. This is particularly useful when you do not want to change the structure of your classes to work with POF and Coherence. The POFSerializer
interface provides these methods:
public Object deserialize(PofReader in)
public void serialize(PofWriter out, Object o)
In the cache configuration file, create cache mappings corresponding to the Entities you will be working with. Identify the serializer (such as com.tangosol.io.pof.ConfigurablePofContext
) and the POF configuration file pof-config.xml
. Identify the EclipseLink cache store (such as oracle.eclipselink.coherence.integrated.EclipseLinkJPACacheStore
) in the <cachestore-scheme>
attribute.
Example 4-2 Sample Cache Configuration File
<?xml version="1.0"?> <cache-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.oracle.com/coherence/coherence-cache-config" xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-cache-config http://xmlns.oracle.com/coherence/coherence-cache-config/1.0/coherence-cache-config.xsd"> <caching-scheme-mapping> <cache-mapping> <cache-name>ATTORNEY_JPA_CACHE</cache-name> <scheme-name>eclipselink-jpa-distributed</scheme-name> </cache-mapping> <cache-mapping> <cache-name>CONTACT_JPA_CACHE</cache-name> <scheme-name>eclipselink-jpa-distributed-load</scheme-name> </cache-mapping> ... additional cache mappings ... <caching-schemes> <distributed-scheme> <scheme-name>eclipselink-jpa-distributed-load</scheme-name> <service-name>EclipseLinkJPA</service-name> <serializer> <instance> <class-name>com.tangosol.io.pof.ConfigurablePofContext</class-name> <init-params> <init-param> <param-type>String</param-type> <param-value>trader-pof-config.xml</param-value> </init-param> </init-params> </instance> </serializer> <backing-map-scheme> <read-write-backing-map-scheme> <internal-cache-scheme> <local-scheme/> </internal-cache-scheme> </read-write-backing-map-scheme> </backing-map-scheme> <autostart>true</autostart> </distributed-scheme> <distributed-scheme> <scheme-name>eclipselink-jpa-distributed</scheme-name> <service-name>EclipseLinkJPA</service-name> <serializer> <instance> <class-name>com.tangosol.io.pof.ConfigurablePofContext</class-name> <init-params> <init-param> <param-type>String</param-type> <param-value>trader-pof-config.xml</param-value> </init-param> </init-params> </instance> </serializer> <backing-map-scheme> <read-write-backing-map-scheme> <internal-cache-scheme> <local-scheme/> </internal-cache-scheme> <!-- Define the cache scheme --> <cachestore-scheme> <class-scheme> <class-name>oracle.eclipselink.coherence.integrated.EclipseLinkJPACacheStore</class-name> <init-params> <init-param> <param-type>java.lang.String</param-type> <param-value>{cache-name}</param-value> </init-param> <init-param> <param-type>java.lang.String</param-type> <param-value>coherence-pu</param-value> </init-param> </init-params> </class-scheme> </cachestore-scheme> </read-write-backing-map-scheme> </backing-map-scheme> <autostart>true</autostart> </distributed-scheme> </caching-schemes> </cache-config>
Provide a file that identifies the Entity classes that will participate in POF serialization. Coherence provides a POF configuration file which is named pof-config.xml
by default. Use the file to assign type-ids
to the Entity classes.
The POF configuration file must also contain type-id
entries for the following classes:
oracle.eclipselink.coherence.integrated.internal.cache.WrapperInternal
—This interface is used to access internal attributes of the Entity wrappers.
oracle.eclipselink.coherence.integrated.cache.WrapperPofSerializer
—Associated serializer. This class is used to provide serialization support for the Entity Wrappers within Coherence when you want to access Coherence caches directly. This includes users who have custom Value Extractors.
oracle.eclipselink.coherence.integrated.internal.querying.EclipseLinkExtractor
—This interface is used for Coherence POF serialization to mark an EclipseLink Extractor for serialization. It extracts values from TopLink Grid entities for Filters.
oracle.eclipselink.coherence.integrated.cache.ExtractorSerializer
—Associated serializer. This class is used to provide serialization support for the Entity Wrappers within Coherence when you want to access the Coherence caches directly. This includes users who have custom Value Extractors.
oracle.eclipselink.coherence.integrated.internal.cache.VersionPutProcessor
—An internal file, used for optimistic lock-aware updates to the grid.
oracle.eclipselink.coherence.integrated.internal.cache.VersionRemoveProcessor
—An internal file, used for optimistic lock-aware removals from the grid.
oracle.eclipselink.coherence.integrated.internal.cache.RelationshipUpdateProcessor
—An internal file, used to update lazy-loaded relationship data into the Grid.
oracle.eclipselink.coherence.integrated.internal.querying.EclipseLinkFilterFactory$SubClassOf
—An internal file. This is a Filter extension that filters on the type of Entity, eliminating superclasses from polymorphic queries.
Example 4-3 illustrates a sample POF configuration file that includes the TopLink Grid support files.
Example 4-3 Sample POF Configuration File
<?xml version="1.0"?> <pof-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.oracle.com/coherence/coherence-pof-config" xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-pof-config http://xmlns.oracle.com/coherence/coherence-pof-config/1.0/coherence-pof-config.xsd"> <user-type-list> <!-- include all "standard" Coherence POF user types --> <include>coherence-pof-config.xml</include> <user-type> <type-id>1163</type-id> <class-name>oracle.toplinkgrid.codesample.pof.models.trader.Attorney</class-name> </user-type> ... additional type IDs for Entity classes ... <user-type> <type-id>1144</type-id> <class-name>oracle.eclipselink.coherence.integrated.internal.cache.WrapperInternal</class-name> <serializer> <class-name>oracle.eclipselink.coherence.integrated.cache.WrapperPofSerializer</class-name> </serializer> </user-type> <user-type> <type-id>1142</type-id> <class-name>oracle.eclipselink.coherence.integrated.internal.querying.EclipseLinkExtractor</class-name> <serializer> <class-name>oracle.eclipselink.coherence.integrated.cache.ExtractorSerializer</class-name> </serializer> </user-type> <user-type> <type-id>1141</type-id> <class-name>oracle.eclipselink.coherence.integrated.internal.cache.VersionPutProcessor</class-name> </user-type> <user-type> <type-id>1140</type-id> <class-name>oracle.eclipselink.coherence.integrated.internal.cache.VersionRemoveProcessor</class-name> </user-type> <user-type> <type-id>1139</type-id> <class-name>oracle.eclipselink.coherence.integrated.internal.cache.RelationshipUpdateProcessor</class-name> </user-type> <user-type> <type-id>1138</type-id> <class-name>oracle.eclipselink.coherence.integrated.internal.querying.EclipseLinkFilterFactory$SubClassOf</class-name> </user-type> </user-type-list> <allow-interfaces>true</allow-interfaces> <allow-subclasses>true</allow-subclasses> </pof-config>