如何解决Cassandra Java Driver 3.11中date与java.util.Date的CodecNotFoundException?
解决Cassandra Java Driver 3.11中date类型与java.util.Date的CodecNotFoundException问题
问题原因
Cassandra的date类型仅存储日期信息(无时间、时区),对应Java 8+的java.time.LocalDate类型。而Driver 3.11默认未提供java.util.Date与Cassandradate之间的转换Codec,因此直接使用java.util.Date操作会抛出该异常。
解决方法
方法1:改用LocalDate(推荐,贴合类型语义)
将代码中的java.util.Date替换为java.time.LocalDate,直接匹配Cassandra的date类型:
System.out.println("Enter date of birth (yyyy-MM-dd):"); String dateOfBirth = scanner.nextLine(); // 使用Java 8+的DateTimeFormatter解析 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); LocalDate birthDate; try { birthDate = LocalDate.parse(dateOfBirth, formatter); } catch (DateTimeParseException e) { e.printStackTrace(); continue; } // 存入Cassandra时直接传入birthDate即可
方法2:自定义Codec(保留java.util.Date时使用)
如果必须使用java.util.Date,可以自定义转换Codec并注册到驱动:
- 实现自定义Codec类:
import com.datastax.driver.core.TypeCodec; import com.datastax.driver.core.ProtocolVersion; import com.datastax.driver.core.exceptions.InvalidTypeException; import java.nio.ByteBuffer; import java.util.Date; import java.time.LocalDate; import java.time.ZoneId; public class UtilDateToCassandraDateCodec extends TypeCodec<Date> { private final TypeCodec<LocalDate> localDateCodec = TypeCodec.date(); public UtilDateToCassandraDateCodec() { super(localDateCodec.getCqlType(), Date.class); } @Override public ByteBuffer serialize(Date value, ProtocolVersion protocolVersion) throws InvalidTypeException { if (value == null) return null; LocalDate localDate = value.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); return localDateCodec.serialize(localDate, protocolVersion); } @Override public Date deserialize(ByteBuffer bytes, ProtocolVersion protocolVersion) throws InvalidTypeException { if (bytes == null) return null; LocalDate localDate = localDateCodec.deserialize(bytes, protocolVersion); return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); } @Override public Date parse(String value) throws InvalidTypeException { if (value == null || value.isEmpty() || value.equals("NULL")) return null; LocalDate localDate = localDateCodec.parse(value); return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); } @Override public String format(Date value) throws InvalidTypeException { if (value == null) return "NULL"; LocalDate localDate = value.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); return localDateCodec.format(localDate); } }
- 注册Codec到Cluster:
Cluster cluster = Cluster.builder() .addContactPoints("你的Cassandra地址") .withCodecRegistry(new CodecRegistry().register(new UtilDateToCassandraDateCodec())) .build(); Session session = cluster.connect();
注意事项
- 方法1需确保项目使用Java 8及以上版本,Driver 3.11原生支持
java.time相关类型。 - 自定义Codec时需注意时区转换逻辑,示例中使用系统默认时区,可根据业务需求调整为固定时区(如
ZoneOffset.UTC)。
内容的提问来源于stack exchange,提问作者Mansi Bora
相关产品推荐
相关产品推荐

