Using custom codecs
The mapper can take advantage of custom codecs to apply custom conversions to mapped columns and fields.
Declaring codecs
Let’s assume you have a table containing a timestamp column:
create table user(id int primary key, birth timestamp);
You’ve created a custom class, and the codec to convert it:
public class MyCustomDate { ... }
public class MyCustomDateCodec extends TypeCodec<MyCustomDate> {
    public MyCustomDate() {
        super(DataType.timestamp(), MyCustomDate.class);
    }
    ...
}
Pre-registered codecs
If you register your codec with the mapper’s underlying DseCluster, it
will be automatically available to the mapper:
DseCluster cluster = DseCluster.builder()
    .addContactPoint("127.0.0.1")
    .withCodecRegistry(
        new CodecRegistry().register(new MyCustomDateCodec())
    ).build();
MappingManager mappingManager = new MappingManager(cluster.connect());
You can normally create your mapped classes using your custom type, without any additional configuration:
@Table(name = "user")
public class User {
  @PartitionKey
  private int id;
  private MyCustomDate birth;
  ... // getters and setters
}
This also works in accessors:
@Accessor
interface UserAccessor {
  @Query("update user set birth = :b where id = :i")
  void updateBirth(@Param("i") int id,
                   @Param("b") MyCustomDate birth);
}
One-time declaration
Sometimes you might want to use your codec only for one particular
column/field. In that case you won’t register it when initializing the
DseCluster:
DseCluster cluster = DseCluster.builder()
    .addContactPoint("127.0.0.1")
    .build();
MappingManager mappingManager = new MappingManager(cluster.connect());
Instead, reference the codec’s class in the @Column annotation:
@Table(name = "user")
public class User {
  @PartitionKey
  private int id;
  @Column(codec = MyCustomDateCodec.class)
  private MyCustomDate birth;
  ... // getters and setters
}
The class must have a no-arg constructor. The mapper will create an instance (one per column) and cache it for future use.
This also works with @Field and @Param annotations.
Implicit UDT codecs
The mapper uses custom codecs internally to handle UDT conversions: when
you register an entity, the mapper inspects
the type of all fields to find classes annotated with
@UDT (this works recursively with
nested UDTs and collections). For each class, the mapper creates a codec
and registers it with the underlying DseCluster.
@UDT(name = "address")
public class Address { ... }
@Entity(name = "user")
public class User {
  ...
  private Address address;
  ...
}
Mapper<User> userMapper = mappingManager.mapper(User.class);
// Codec is now registered for Address <-> CQL address
A nice side-effect is that you can now use the @UDT-annotated class
with any driver method, not just mapper methods:
Row row = session.execute("select address from user where id = 1").one();
Address address = row.get("address", Address.class);
If you don’t use entity mappers but still want the convenience of the UDT codec for core driver methods, the mapper provides a way to create it independently:
mappingManager.udtCodec(Address.class);
// Codec is now registered
