pandaforme
pandaforme

Reputation: 163

How to convert Cassandra UDT to Optional type

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

Upvotes: 3

Views: 1148

Answers (2)

Pavel Voropaev
Pavel Voropaev

Reputation: 63

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.

Upvotes: 0

Olivier Michallat
Olivier Michallat

Reputation: 2312

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);

Upvotes: 5

Related Questions