I have cassandra table with a date type column as follows:
create table people
(
id int primary key,
name text,
email text,
dob date
);
I am using SpringBoot 1.5.2 + Spring Data Cassandra Starter.
@Table("people")
public class Person {
@PrimaryKey
Integer id;
private String name;
private String email;
private java.util.Date dob;
//setters and getters
}
public interface PersonRepository extends CrudRepository<Person, Integer>{
}
I am inserting new Person as follows:
personRepository.save(new Person(1, "Siva","[email protected]", new java.util.Date()));
It is throwing the following error:
Caused by: com.datastax.driver.core.exceptions.InvalidQueryException: Expected 4 byte long for date (8)
at com.datastax.driver.core.Responses$Error.asException(Responses.java:136) ~[cassandra-driver-core-3.1.4.jar:na]
at com.datastax.driver.core.DefaultResultSetFuture.onSet(DefaultResultSetFuture.java:179) ~[cassandra-driver-core-3.1.4.jar:na]
at com.datastax.driver.core.RequestHandler.setFinalResult(RequestHandler.java:177) ~[cassandra-driver-core-3.1.4.jar:na]
at com.datastax.driver.core.RequestHandler.access$2500(RequestHandler.java:46) ~[cassandra-driver-core-3.1.4.jar:na]
But if I make dob column type to timestamp then it is working fine. Is it possible to have date type column and use java.util.Date type properties?
P.s: Even if I use java.sql.Date I am getting the same error.
Use com.datastax.driver.core.LocalDate
You can use any of these method to get LocalDate
from java.util.Date
Or you could create your own codec that will allow you to insert java.util.Date
into Cassandra date type.
You can start like the below one :
public class DateCodec extends TypeCodec<Date> {
private final TypeCodec<LocalDate> innerCodec;
public DateCodec(TypeCodec<LocalDate> codec, Class<Date> javaClass) {
super(codec.getCqlType(), javaClass);
innerCodec = codec;
}
@Override
public ByteBuffer serialize(Date value, ProtocolVersion protocolVersion) throws InvalidTypeException {
return innerCodec.serialize(LocalDate.fromMillisSinceEpoch(value.getTime()), protocolVersion);
}
@Override
public Date deserialize(ByteBuffer bytes, ProtocolVersion protocolVersion) throws InvalidTypeException {
return new Date(innerCodec.deserialize(bytes, protocolVersion).getMillisSinceEpoch());
}
@Override
public Date parse(String value) throws InvalidTypeException {
return new Date(innerCodec.parse(value).getMillisSinceEpoch());
}
@Override
public String format(Date value) throws InvalidTypeException {
return value.toString();
}
}
When creating connectin you have to register :
CodecRegistry codecRegistry = new CodecRegistry();
codecRegistry.register(new DateCodec(TypeCodec.date(), Date.class));
Cluster.builder().withCodecRegistry(codecRegistry).build();
For more : http://docs.datastax.com/en/developer/java-driver/3.1/manual/custom_codecs/