3

I have a User table and its corresponding POJO

@Table
public class User{
  @Column(name = "id")
  private String id; 

  // lots of fields

  @Column(name = "address")
  @Frozen
  private Optional<Address> address;   

  // getters and setters
}

@UDT
public class Address {
  @Field(name = "id")
  private String id;

  @Field(name = "country")
  private String country;

  @Field(name = "state")
  private String state;

  @Field(name = "district")
  private String district;

  @Field(name = "street")
  private String street;

  @Field(name = "city")
  private String city;

  @Field(name = "zip_code")
  private String zipCode;

  // getters and setters 
}

I wanna convert UDT "address" to Optional. Because I use "cassandra-driver-mapping:3.0.0-rc1" and "cassandra-driver-extras:3.0.0-rc1", there are lots of codec I can use them.

For example: OptionalCodec

I wanna register it to CodecRegistry and pass TypeCodec to OptionalCodec's constructor.

But TypeCodec is a abstract class, I can't initiate it.

Someone have any idea how to initiate OptionalCodec?


Thank you, @Olivier Michallat. Your solution is OK!

But I'm a little confused to set OptionalCodec to CodecRegistry. You must initial a session at first. Then pass session to MappingManager, get correct TypeCodec and register codecs.

It's a little weird that you must initial session at first, in order to get TypeCodec !?

Cluster cluster = Cluster.builder()
                         .addContactPoints("127.0.0.1")
                         .build();
Session session = cluster.connect(...);
cluster.getConfiguration()
       .getCodecRegistry()
       .register(new OptionalCodec(new MappingManager(session).udtCodec(Address.class)))
       .register(...);
// use session to operate DB
pandaforme
  • 153
  • 1
  • 9
  • The session needs to be initialized in order to build the codec: the UDT definition is retrieved from the database (because your mapped class could map only part of the fields, so if we built the definition from the client-side it could be missing fields). Also, if you don't declare a keyspace in your `@UDT` annotation, it needs to read the session's default keyspace. – Olivier Michallat Jan 18 '16 at 13:53

2 Answers2

5

The MappingManager has a method that will create the codec from the annotated class:

TypeCodec<Address> addressCodec = mappingManager.udtCodec(Address.class);
OptionalCodec<Address> optionalAddressCodec = new OptionalCodec(addressCodec);
codecRegistry.register(optionalAddressCodec);
Olivier Michallat
  • 2,302
  • 11
  • 13
0

Not really an answer but hope it helps. I couldn't make the Optional work with UDT in scala. However List and Array are working fine:

Here is a scala solution for driver version 4.x:

val reg = session.getContext.getCodecRegistry
val yourTypeUdt: UserDefinedType = session.getMetadata.getKeyspace(keyspace).flatMap(_.getUserDefinedType("YOUR_TYPE")).get
val yourTypeCodec: TypeCodec[UserDefinedType] = reg.codecFor(yourTypeUdt)
reg.asInstanceOf[MutableCodecRegistry].register(TypeCodecs.listOf(yourTypeCodec))

Don't forget to use java.util.* instead of your normal scala types.