title: Custom Cassandra converter
body: <p>I'v started looking for nice solution how to nicely persist entity using Spring CassandraOperations. The problems started because some fields within my entity is not cassandra supported, e.g. joda DateTime.</p>
  
  <p>The workaround is to have additional fields within the same entity of type java.util.Date instead of joda DateTime, mark unrequired fields with @Transient. But this is not clean, so I started looking for automatic custom conversion.</p>
  
  <p>Currently spring-data-cassandra reference does not provide information how to register custom converter. <a href="http://docs.spring.io/spring-data/cassandra/docs/current/reference/html/#cassandra.custom-converters" rel="nofollow noreferrer">http://docs.spring.io/spring-data/cassandra/docs/current/reference/html/#cassandra.custom-converters</a></p>
  
  <p>Is it possible to register custom converter (like here <a href="https://stackoverflow.com/questions/28606197/spring-data-cassandra-localdatetime-conversion">Spring Data Cassandra LocalDateTime Conversion</a>) in CassandraSessionFactoryBean?</p>
  
  <p>This is my code
  @Configuration
  public class CassandraConfig {</p>
  
  <pre><code>@Value("${cassandra.contactpoints}")
  private String cassandraContactPoint;
  
  @Value("${cassandra.port}")
  private int cassandraPort;
  
  @Value("${cassandra.keyspace}")
  private String cassandraKeySpace;
  
  @Bean
  public CassandraClusterFactoryBean cluster() {
  
      CassandraClusterFactoryBean cluster = new CassandraClusterFactoryBean();
      cluster.setContactPoints(cassandraContactPoint);
      cluster.setPort(cassandraPort);
  
      return cluster;
  }
  
  @Bean
  public CassandraMappingContext mappingContext() {
      return new BasicCassandraMappingContext();
  }
  
  @Bean
  public CassandraConverter converter() {
      return new MappingCassandraConverter(mappingContext());
  }
  
  @Bean
  public CassandraSessionFactoryBean session() throws Exception {
      CassandraSessionFactoryBean session = new CassandraSessionFactoryBean();
      session.setCluster(cluster().getObject());
      session.setKeyspaceName(cassandraKeySpace);
      session.setConverter(converter());
      session.setSchemaAction(SchemaAction.NONE);
  
      return session;
  }
  
  @Bean
  public CassandraOperations cassandraTemplate() throws Exception {
      return new CassandraTemplate(session().getObject());
  }
  
  @Bean
  public ConversionService getConversionService() {
      ConversionServiceFactoryBean bean = new ConversionServiceFactoryBean();
      bean.setConverters(new HashSet&lt;&gt;(getConverters()));
      bean.afterPropertiesSet();
  
      return bean.getObject();
  }
  
  private Set&lt;Converter&lt;?, ?&gt;&gt; getConverters() {
      Set&lt;Converter&lt;?, ?&gt;&gt; converters = new HashSet&lt;&gt;();
      converters.addAll(Jsr310Converters.getConvertersToRegister());
      converters.add(new DateTimeWriteConverter());
      converters.add(new DateTimeReadConverter());
  
      return converters;
  }
  
  public static class DateTimeWriteConverter implements Converter&lt;DateTime, Long&gt; {
      @Override
      public Long convert(DateTime source) {
          return source.getMillis();
      }
  }
  
  public static class DateTimeReadConverter implements Converter&lt;Long, DateTime&gt; {
      @Override
      public DateTime convert(Long source) {
          return new DateTime(source);
      }
  }
  </code></pre>
  
  <p>}</p>