JDO : Persistable Field Types

When persisting a class, a persistence solution needs to know how to persist the types of each field in the class. Clearly a persistence solution can only support a finite number of Java types; it cannot know how to persist every possible type creatable. The JDO specification define lists of types that are required to be supported by all implementations of those specifications. This support can be conveniently split into two parts

  • First-Class (FCO) Types : An object that can be referred to (object reference, providing a relation) and that has an "identity" is termed a First Class Object (FCO). DataNucleus supports the following Java types as FCO :
    • persistable : any class marked for persistence can be persisted with its own identity in the datastore
    • interface where the field represents a persistable object
    • java.lang.Object where the field represents a persistable object
  • Second-Class (SCO) Types : An object that does not have an "identity" is termed a Second Class Object (SCO). This is something like a String or Date field in a class, or alternatively a Collection (that contains other objects). The sections below shows the currently supported SCO java types in DataNucleus. The tables in these sections show
    • Extension? : whether the type is JDO standard, or is a DataNucleus extension
    • default-fetch-group (DFG) : whether the field is retrieved by default when retrieving the object itself
    • persistence-modifier : whether the field is persisted by default, or whether the user has to mark the field as persistent in XML/annotations to persist it
    • proxied : whether the field is represented by a "proxy" that intercepts any operations to detect whether it has changed internally.
    • primary-key : whether the field can be used as part of the primary-key

Where you have a secondary type that can be persisted in multiple possible ways you select which column type(s) by using the jdbc-type for the field, or alternatively you find the name of the internal DataNucleus TypeConverter and use that via the metadata extension "type-converter-name".


If you have support for any additional types and would either like to contribute them, or have them listed here, let us know. Supporting a new type is easy, typically involving a JDO AttributeConverter if you can easily convert the type into a String or Long. See also the Java Types plugin-point You can also define more specific support for it with RDBMS datastores - See the RDBMS Java Types plugin-point

Handling of second-class types uses wrappers and bytecode enhancement with DataNucleus. This contrasts to what Hibernate uses (proxies), and what Hibernate imposes on you. See this blog entry if you have doubts about this approach.


Primitive and java.lang Types

All primitive types and wrappers are supported and will be persisted into a single database "column". Arrays of these are also supported, and can either be serialised into a single column, or persisted into a join table (dependent on datastore).

Java Type Extension? DFG? Persistent? Proxied? PK? Comments
boolean Persisted as BOOLEAN, Integer (i.e 1,0), String (i.e 'Y','N').
byte
char
double
float
int
long
short
java.lang.Boolean Persisted as BOOLEAN, Integer (i.e 1,0), String (i.e 'Y','N').
java.lang.Byte
java.lang.Character
java.lang.Double
java.lang.Float
java.lang.Integer
java.lang.Long
java.lang.Short
java.lang.Number Persisted in a column capable of storing a BigDecimal, and will store to the precision of the object to be persisted. On reading back the object will be returned typically as a BigDecimal since there is no mechanism for determing the type of the object that was stored.
java.lang.String
java.lang.StringBuffer Persisted as String. The dirty check mechanism for this type is limited to immutable mode, which means if you change a StringBuffer object field, you must reassign it to the owner object field to make sure changes are propagated to the database.
java.lang.StringBuilder Persisted as String. The dirty check mechanism for this type is limited to immutable mode, which means if you change a StringBuffer object field, you must reassign it to the owner object field to make sure changes are propagated to the database.
java.lang.Class Persisted as String.

java.math types

BigInteger and BigDecimal are supported and persisted into a single numeric column by default.

Java Type Extension? DFG? Persistent? Proxied? PK? Comments
java.math.BigDecimal Persisted as DOUBLE or String. String can be used to retain precision.
java.math.BigInteger Persisted as INTEGER or String. String can be used to retain precision.

Temporal Types (java.util, java.sql. java.time, Jodatime)

DataNucleus supports a very wide range of temporal types, with flexibility in how they are persisted.

Java Type Extension? DFG? Persistent? Proxied? PK? Comments
java.sql.Date Persisted as DATE, String, DATETIME or Long.
java.sql.Time Persisted as TIME, String, DATETIME or Long.
java.sql.Timestamp Persisted as TIMESTAMP, String or Long.
java.util.Calendar Persisted as TIMESTAMP (inc Timezone), DATETIME, String, or as (Long, String) storing millis + timezone respectively
java.util.GregorianCalendar Persisted as TIMESTAMP (inc Timezone), DATETIME, String, or as (Long, String) storing millis + timezone respectively
java.util.Date Persisted as DATETIME, String or Long.
java.util.TimeZone Persisted as String.
java.time.LocalDateTime Persisted as Timestamp, String, or DATETIME.
java.time.LocalTime Persisted as TIME, String, or Long.
java.time.LocalDate Persisted as DATE, String, or DATETIME.
java.time.OffsetDateTime Persisted as Timestamp, String, or DATETIME.
java.time.OffsetTime Persisted as TIME, String, or Long.
java.time.MonthDay Persisted as String, DATE, or as (Integer,Integer) with the latter being month+day respectively.
java.time.YearMonth Persisted as String, DATE, or as (Integer,Integer) with the latter being year+month respectively.
java.time.Year Persisted as Integer, or String.
java.time.Period Persisted as String.
java.time.Instant Persisted as TIMESTAMP, String, Long, or DATETIME.
java.time.Duration Persisted as String, Double (secs.nanos), or Long (secs).
java.time.ZoneId Persisted as String.
java.time.ZoneOffset Persisted as String.
java.time.ZonedDateTime Persisted as Timestamp, or String.
org.joda.time.DateTime Requires datanucleus-jodatime plugin. Persisted as TIMESTAMP or String.
org.joda.time.LocalTime Requires datanucleus-jodatime plugin. Persisted as TIME or String.
org.joda.time.LocalDate Requires datanucleus-jodatime plugin. Persisted as DATE or String.
org.joda.time.LocalDateTime Requires datanucleus-jodatime plugin. Persisted as TIMESTAMP, or String.
org.joda.time.Duration Requires datanucleus-jodatime plugin. Persisted as String or Long.
org.joda.time.Interval Requires datanucleus-jodatime plugin. Persisted as String or (TIMESTAMP, TIMESTAMP).
org.joda.time.Period Requires datanucleus-jodatime plugin. Persisted as String.

Collection/Map types

DataNucleus supports a very wide range of collection, list and map types.

Java Type Extension? DFG? Persistent? Proxied? PK? Comments
java.util.ArrayList See the 1-N Lists Guide
java.util.BitSet Persisted as collection by default, but will be stored as String when the datastore doesn't provide for collection storage
java.util.Collection See the 1-N Collections Guide
java.util.HashMap See the 1-N Maps Guide
java.util.HashSet See the 1-N Collections Guide
java.util.Hashtable See the 1-N Maps Guide
java.util.LinkedHashMap Persisted as a Map currently. No List-ordering is supported. See the 1-N Maps Guide
java.util.LinkedHashSet Persisted as a Set currently. No List-ordering is supported. See the 1-N Collections Guide
java.util.LinkedList See the 1-N Lists Guide
java.util.List See the 1-N Lists Guide
java.util.Map See the 1-N Maps Guide
java.util.Properties See the 1-N Maps Guide
java.util.PriorityQueue The comparator is specifiable via the metadata extension comparator-name (see below). See the 1-N Lists Guide
java.util.Queue The comparator is specifiable via the metadata extension comparator-name (see below). See the 1-N Lists Guide
java.util.Set See the 1-N Collections Guide
java.util.SortedMap The comparator is specifiable via the metadata extension comparator-name (see below). See the 1-N Maps Guide
java.util.SortedSet The comparator is specifiable via the metadata extension comparator-name (see below). See the 1-N Collections Guide
java.util.Stack See the 1-N Lists Guide
java.util.TreeMap The comparator is specifiable via the metadata extension comparator-name (see below). See the 1-N Maps Guide
java.util.TreeSet The comparator is specifiable via the metadata extension comparator-name (see below). See the 1-N Collections Guide
java.util.Vector See the 1-N Lists Guide
com.google.common.collect.Multiset Requires datanucleus-guava plugin. See the 1-N Collections Guide

Comparators

Containers that support a Comparator to order the elements of the set can specify it in metadata like this.

    @Element
    @Extension(vendorName="datanucleus", key="comparator-name", value="mydomain.model.MyComparator")
    SortedSet<MyElementType> elements; 

When instantiating the SortedSet field it will create it with a comparator of the specified class (which must have a default constructor).


Enums

DataNucleus supports persisting Enums, and they can be stored as either the ordinal (numeric column) or name (String column).

Java Type Extension? DFG? Persistent? Proxied? PK? Comments
java.lang.Enum Persisted as String (name) or int (ordinal). Specified via jdbc-type.

A DataNucleus extension to this is where you have an Enum that defines its own "value"s for the different enum options. Note that this is applicable to RDBMS, MongoDB, Cassandra, Neo4j, HBase, Excel, ODF and JSON currently.

public enum MyColour
{
    RED((short)1), GREEN((short)3), BLUE((short)5), YELLOW((short)8);

    private short value;

    private MyColour(short value)
    {
        this.value = value;
    }

    public short getValue() 
    {
        return value;
    }
}

With the default persistence it would persist as String-based, so persisting "RED" "GREEN" "BLUE" etc. With jdbc-type as INTEGER it would persist 0, 1, 2, 3 being the ordinal values. If you define the metadata as

@Extension(vendorName="datanucleus", key="enum-value-getter", value="getValue")
MyColour colour;

this will now persist 1, 3, 5, 8, being the "value" of each of the enum options. You can use this method to persist "int", "short", or "String" types.


A DataNucleus extension is available for RDBMS datastores where you are storing the name of the enum, and to put a CHECK constraint on the column. You specify it like this

@Extension(vendorName="datanucleus", key="enum-check-constraint", value="true")
MyColour colour;

Geospatial Types

DataNucleus has extensive support for Geospatial types. The datanucleus-geospatial plugin allows using geospatial and traditional types simultaneously in persistent objects making DataNucleus a single interface to read and manipulate any business data. The implementation of many of these spatial types follows the OGC Simple Feature specification, but adds further types where the datastores support them.

Java Type Extension? DFG? Persistent? Proxied? PK? Comments
java.awt.Point Requires datanucleus-geospatial plugin. Persisted as (int, int) on RDBMS, or as String elsewhere.
java.awt.Rectangle Requires datanucleus-geospatial plugin. Persisted as (int, int, int, int) on RDBMS, or as String elsewhere.
java.awt.Polygon Requires datanucleus-geospatial plugin. Persisted as (int[], int[], int) on RDBMS, or as String elsewhere.
java.awt.geom.Line2D Requires datanucleus-geospatial plugin. Persisted as (double, double, double, double) or (float, float, float, float) on RDBMS, or as String elsewhere.
java.awt.geom.Point2D Requires datanucleus-geospatial plugin. Persisted as (double, double) or (float, float) on RDBMS, or as String elsewhere.
java.awt.geom.Rectangle2D Requires datanucleus-geospatial plugin. Persisted as (double, double, double, double) or (float, float, float, float) on RDBMS, or as String elsewhere.
java.awt.geom.Arc2D Requires datanucleus-geospatial plugin. Persisted as (double, double, double, double, double, double, int) or (float, float, float, float, float, float, int) on RDBMS, or as String elsewhere.
java.awt.geom.CubicCurve2D Requires datanucleus-geospatial plugin. Persisted as (double, double, double, double, double, double, doubel, double) or (float, float, float, float, float, float, float, float) on RDBMS, or as String elsewhere.
java.awt.geom.Ellipse2D Requires datanucleus-geospatial plugin Persisted as (double, double, double, double) or (float, float, float, float) on RDBMS, or as String elsewhere.
java.awt.geom.QuadCurve2D Requires datanucleus-geospatial plugin. Persisted as (double, double, double, double, double, double) or (float, float, float, float, float, float) on RDBMS, or as String elsewhere.
java.awt.geom.RoundRectangle2D Requires datanucleus-geospatial plugin. Persisted as (double, double, double, double, double, double) or (float, float, float, float, float, float) on RDBMS, or as String elsewhere.
oracle.spatial.geometry.JGeometry Requires datanucleus-geospatial plugin. Dirty check limited to immutable mode (must reassign field to owner if you change it). Only on Oracle(SDO_GEOMETRY), MySQL(geometry)
com.vividsolutions.jts.geom.Geometry Requires datanucleus-geospatial plugin. Dirty check limited to immutable mode (must reassign field to owner if you change it). Only on Oracle(SDO_GEOMETRY), MySQL(geometry), PostGIS(geometry).
com.vividsolutions.jts.geom.GeometryCollection Requires datanucleus-geospatial plugin. Dirty check limited to immutable mode (must reassign field to owner if you change it). Only on Oracle(SDO_GEOMETRY), MySQL(geometry), PostGIS(geometry).
com.vividsolutions.jts.geom.LinearRing Requires datanucleus-geospatial plugin. Dirty check limited to immutable mode (must reassign field to owner if you change it). Only on Oracle(SDO_GEOMETRY), MySQL(geometry), PostGIS(geometry).
com.vividsolutions.jts.geom.LineString Requires datanucleus-geospatial plugin. Dirty check limited to immutable mode (must reassign field to owner if you change it). Only on Oracle(SDO_GEOMETRY), MySQL(geometry), PostGIS(geometry).
com.vividsolutions.jts.geom.MultiLineString Requires datanucleus-geospatial plugin. Dirty check limited to immutable mode (must reassign field to owner if you change it). Only on Oracle(SDO_GEOMETRY), MySQL(geometry), PostGIS(geometry).
com.vividsolutions.jts.geom.MultiPoint Requires datanucleus-geospatial plugin. Dirty check limited to immutable mode (must reassign field to owner if you change it). Only on Oracle(SDO_GEOMETRY), MySQL(geometry), PostGIS(geometry).
com.vividsolutions.jts.geom.MultiPolygon Requires datanucleus-geospatial plugin. Dirty check limited to immutable mode (must reassign field to owner if you change it). Only on Oracle(SDO_GEOMETRY), MySQL(geometry), PostGIS(geometry).
com.vividsolutions.jts.geom.Point Requires datanucleus-geospatial plugin. Dirty check limited to immutable mode (must reassign field to owner if you change it). Only on Oracle(SDO_GEOMETRY), MySQL(geometry), PostGIS(geometry).
com.vividsolutions.jts.geom.Polygon Requires datanucleus-geospatial plugin. Dirty check limited to immutable mode (must reassign field to owner if you change it). Only on Oracle(SDO_GEOMETRY), MySQL(geometry), PostGIS(geometry).
org.postgis.Geometry Requires datanucleus-geospatial plugin. Dirty check limited to immutable mode (must reassign field to owner if you change it). Only on MySQL(geometry), PostGIS(geometry).
org.postgis.GeometryCollection Requires datanucleus-geospatial plugin. Dirty check limited to immutable mode (must reassign field to owner if you change it). Only on MySQL(geometry), PostGIS(geometry).
org.postgis.LinearRing Requires datanucleus-geospatial plugin. Dirty check limited to immutable mode (must reassign field to owner if you change it). Only on MySQL(geometry), PostGIS(geometry).
org.postgis.LineString Requires datanucleus-geospatial plugin. Dirty check limited to immutable mode (must reassign field to owner if you change it). Only on MySQL(geometry), PostGIS(geometry).
org.postgis.MultiLineString Requires datanucleus-geospatial plugin. Dirty check limited to immutable mode (must reassign field to owner if you change it). Only on MySQL(geometry), PostGIS(geometry).
org.postgis.MultiPoint Requires datanucleus-geospatial plugin. Dirty check limited to immutable mode (must reassign field to owner if you change it). Only on MySQL(geometry), PostGIS(geometry).
org.postgis.MultiPolygon Requires datanucleus-geospatial plugin. Dirty check limited to immutable mode (must reassign field to owner if you change it). Only on MySQL(geometry), PostGIS(geometry).
org.postgis.Point Requires datanucleus-geospatial plugin. Dirty check limited to immutable mode (must reassign field to owner if you change it). Only on MySQL(geometry), PostGIS(geometry).
org.postgis.Polygon Requires datanucleus-geospatial plugin. Dirty check limited to immutable mode (must reassign field to owner if you change it). Only on MySQL(geometry), PostGIS(geometry).
org.postgis.PGbox2d Requires datanucleus-geospatial plugin. Dirty check limited to immutable mode (must reassign field to owner if you change it). Only on PostGIS(geometry).
org.postgis.PGbox3d Requires datanucleus-geospatial plugin. Dirty check limited to immutable mode (must reassign field to owner if you change it). Only on PostGIS(geometry).

Some extra notes for implementation of JTS, JGeometry and PostGIS types support :-

  • MySQL doesn't support 3-dimensional geometries. Trying to persist them anyway results in undefined behaviour, there may be an exception thrown or the z-ordinate might just get stripped.
  • Oracle supports additional data types like circles and curves that are not defined in the OGC SF specification. Any attempt to read or persist one of those data types, if you're not using Oracle, will result in failure!
  • PostGIS added support for curves in version 1.2.0, but at the moment the JDBC driver doesn't support them yet. Any attempt to read curves geometries will result in failure, for every mapping scenario!
  • Both PostGIS and Oracle have a system to add user data to specific points of a geometry. In PostGIS these types are called measure types and the z-coordinate of every 2d-point can be used to store arbitrary (numeric) data of double precision associated with that point. In Oracle this user data is called LRS. datanucleus-geospatial tries to handle these types as gracefully as possible. But the recommendation is to not use them, unless you have a mapping scenario that is known to support them.
  • PostGIS supports two additional types called box2d and box3d, that are not defined in OGC SF. There are only mappings available for these types for PostGIS, any attempt to read or persist one of those data types in another mapping scenario will result in failure!

datanucleus-geospatial has defined some metadata extensions that can be used to give additional information about the geometry types in use. The position of these tags in the meta-data determines their scope. If you use them inside a <field>-tag the values are only used for that field specifically, if you use them inside the <package>-tag the values are in effect for all (geometry) fields of all classes inside that package, etc.

<package name="org.datanucleus.samples.jtsgeometry">
    <extension vendor-name="datanucleus" key="spatial-dimension" value="2"/> [1]
    <extension vendor-name="datanucleus" key="spatial-srid" value="4326"/> [1]

    <class name="SampleGeometry" detachable="true">
        <field name="id"/>
        <field name="name"/>
        <field name="geom" persistence-modifier="persistent">
            <extension vendor-name="datanucleus" key="mapping" value="no-userdata"/> [2]
        </field>
    </class>

    <class name="SampleGeometryCollectionM" table="samplejtsgeometrycollectionm" detachable="true">
        <extension vendor-name="datanucleus" key="postgis-hasMeasure" value="true"/> [3]
        <field name="id"/>
        <field name="name"/>
        <field name="geom" persistence-modifier="persistent"/>
    </class>

    <class name="SampleGeometryCollection3D" table="samplejtsgeometrycollection3d" detachable="true">
        <extension vendor-name="datanucleus" key="spatial-srid" value="-1"/> [1]
        <extension vendor-name="datanucleus" key="spatial-dimension" value="3"/> [1]
        <field name="id"/>
        <field name="name"/>
        <field name="geom" persistence-modifier="persistent"/>
    </class>
</package>
  • [1] - The srid & dimension values are used in various places. One of them is schema creation, when using PostGIS, another is when you query the SpatialHelper.
  • [2] - Every JTS geometry object can have a user data object attached to it. The default behaviour is to serialize that object and store it in a separate column in the database. If for some reason this isn't desired, the mapping extension can be used with value "no-mapping" and DataNucleus-Geospatial will ignore the user data objects.
  • [3] - If you want to use measure types in PostGIS you have to define that using the postgis-hasMeasure extension.

Other Types

Many other types are supported.

Java Type Extension? DFG? Persistent? Proxied? PK? Comments
java.lang.Object Either persisted serialised, or represents multiple possible types
java.util.Currency Persisted as String.
java.util.Locale Persisted as String.
java.util.UUID Persisted as String, or alternatively as native uuid on PostgreSQL when specifying sql-type="uuid".
java.util.Optional<type> Persisted as the type of the generic type that optional represents.
java.awt.Color Persisted as String or as (Integer,Integer,Integer,Integer) storing red,green,blue,alpha respectively.
java.awt.image.BufferedImage Persisted as serialised.
java.net.URI Persisted as String.
java.net.URL Persisted as String.
java.io.Serializable Persisted as serialised.
java.io.File Only for RDBMS, persisted to LONGVARBINARY, and retrieved as streamable so as not to adversely affect memory utilisation, hence suitable for large files.

Arrays

The vast majority of the SCO types can also be persisted as arrays of that type as well. Here we list a few of the combinations definitely supported as arrays, but others likely will work fine

Java Type Extension? DFG? Persistent? Proxied? PK? Comments
boolean[] See the Arrays Guide
byte[] See the Arrays Guide
char[] See the Arrays Guide
double[] See the Arrays Guide
float[] See the Arrays Guide
int[] See the Arrays Guide
long[] See the Arrays Guide
short[] See the Arrays Guide
java.lang.Boolean[] See the Arrays Guide
java.lang.Byte[] See the Arrays Guide
java.lang.Character[] See the Arrays Guide
java.lang.Double[] See the Arrays Guide
java.lang.Float[] See the Arrays Guide
java.lang.Integer[] See the Arrays Guide
java.lang.Long[] See the Arrays Guide
java.lang.Short[] See the Arrays Guide
java.lang.String[] See the Arrays Guide
java.util.Date[] See the Arrays Guide
java.math.BigDecimal[] See the Arrays Guide
java.math.BigInteger[] See the Arrays Guide
java.lang.Enum[] See the Arrays Guide
java.util.Locale[] See the Arrays Guide
Persistable[] See the Arrays Guide

Generic Type Variables

JDO does not explicitly require support for generic type variables. DataNucleus does support some situations with generic type variables.

The first example that is largely supported is where you have an abstract base class with a generic Type Variable and then you specify the type in the (concrete) subclass(es).

public abstract class Base<T>
{
    private T id;
}

public class Sub1 extends Base<Long>
{
    ...
}
public class Sub2 extends Base<Integer>
{
    ...
}

Similarly you use TypeVariables to form relations, like this

public abstract class Ownable<T extends Serializable> implements Serializable
{
    @ManyToOne(optional = false)
    private T owner;
}

public class Document extends Ownable<Person>
{
    ...
}

Clearly there are many combinations of where TypeVariables can be used and DataNucleus supports a subset of these currently. Try it and see.

JDO Attribute Converters

JDO3.2 introduces an API for conversion of an attribute of a PersistenceCapable object to its datastore value. You can define a "converter" that will convert to the datastore value and back from it, implementing this interface.

public interface AttributeConverter<X,Y>
{
    public Y convertToDatastore(X attributeValue);

    public X convertToAttribute (Y datastoreValue);
}

so if we have a simple converter to allow us to persist fields of type URL in a String form in the datastore, like this

public class URLStringConverter implements AttributeConverter<URL, String>
{
    public URL convertToAttribute(String str)
    {
        if (str == null)
        {
            return null;
        }

        URL url = null;
        try
        {
            url = new java.net.URL(str.trim());
        }
        catch (MalformedURLException mue)
        {
            throw new IllegalStateException("Error converting the URL", mue);
        }
        return url;
    }

    public String convertToDatastore(URL url)
    {
        return url != null ? url.toString() : null;
    }
}

and now in our PersistenceCapable class we mark any URL field as being converted using this converter

@PersistenceCapable
public class MyClass
{
    @PrimaryKey
    long id;

    @Convert(converter=URLStringConverter.class)
    URL url;

    ...
}

Note that you can register converters as the default handler for a java type when constructing the PMF via persistence properties. These properties should be of the form javax.jdo.option.typeconverter.{javatype} and the value is the class name of the AttributeConverter.

A further use of AttributeConverter is where you want to apply type conversion to the key/value of a Map field, or to the element of a Collection field. The Collection element case is simple, you just specify the @Convert against the field and it will be applied to the element. If you want to apply type conversion to a key/value of a map do this.

    @Key(converter=URLStringConverter.class)
    Map<URL, OtherEntity> myMap;

You CANNOT use an AttributeConverter for a PersistenceCapable type. This is because a PersistenceCapable type requires special treatment, such as attaching a StateManager etc.


TypeConverters

By default DataNucleus will store the value using its own internal configuration/default for the java type and for the datastore. The user can, however, change that by making use of a TypeConverter. You firstly need to define the TypeConverter class (assuming you aren't going to use an internal DataNucleus converter, and for this you should refer to the TypeConverter plugin-point. Once you have the converter defined, and registered in a plugin.xml under a name you then mark the field/property to use it

    @Extension(vendorName="datanucleus", key="type-converter-name", value="kryo-serialise")
    String longString;

In this case we have a String field but we want to serialise it, not using normal Java serialisation but using the "Kryo" library. When it is stored it will be converted into a serialised form and when read back in will be deserialised. You can see the example Kryo TypeConverter over on GitHub.

You CANNOT use a TypeConverter for a PersistenceCapable type. This is because a PersistenceCapable type requires special treatment, such as attaching a StateManager etc.