Cassandra抛出CodecNotFoundException [bigint< - > java.util.Date]

时间:2017-03-02 14:01:53

标签: cassandra

我有一个具有Date类型属性的java实体,我有一个数据库表,它将日期属性存储到bigint cloumn但是当我运行代码时它给了我这个错误:

  

com.datastax.driver.core.exceptions.CodecNotFoundException:找不到请求操作的编解码器:[bigint< - > java.util.Date]

你可以帮我解决cassandra抛出的问题吗?

3 个答案:

答案 0 :(得分:3)

您正在将big.util.Date插入bigint列,这就是您收到此错误的原因。

使用getTime()方法获取以毫秒为单位的时间,这需要很长时间才能插入bigint列。

示例:

Date date = ; // you have the date
long timeInMilis = date.getTime();

使用timeInMilis插入cassandra

您可以将列类型bigint更改为时间戳,然后您可以直接插入java.util.Date,不必以毫秒为单位获取时间,

-------------------------------------
| CQL3 data type    |   Java type    |
|-------------------|----------------|
|     bigint        |    long        |
|-------------------|----------------|
|    timestamp      | java.util.Date |
--------------------------------------

有关CQL的更多信息 - Java Mapping:https://docs.datastax.com/en/developer/java-driver/3.1/manual/#cql-to-java-type-mapping

答案 1 :(得分:2)

我认为问题是您正在尝试将java.util.Date对象存储在cql bigint中。在Java驱动程序中映射到bigint的类型是long(请参阅文档的'CQL to Java type mapping'部分)。

假设您的意思是在此列中存储纪元毫秒,您可以选择几个选项。

  1. 将列类型更改为timestamp,映射到java.util.Date(并通过setTiemstamp / getTimstamp设置/访问)。
  2. setLongDate.getTime()结合使用,将Date转换为代表纪元毫秒的long
  3. 创建并注册将java.util.Date映射到bigint的{​​{3}},即:
  4. import com.datastax.driver.core.*;
    
    import java.util.Date;
    
    public class CodecTest {
    
        static class DateToBigintCodec extends MappingCodec<Date, Long> {
    
            DateToBigintCodec() {
                // creates a mapping from bigint <-> Date.
                super(TypeCodec.bigint(), Date.class);
            }
    
            @Override
            protected Date deserialize(Long value) {
                return new Date(value);
            }
    
            @Override
            protected Long serialize(Date value) {
                return value.getTime();
            }
        }
    
        public static void main(String args[]) {
            TypeCodec<Date> codec = new DateToBigintCodec();
            Cluster cluster = Cluster.builder().addContactPoint("127.0.0.1").build();
            try {
                // register custom codec
                cluster.getConfiguration().getCodecRegistry().register(codec);
    
                Date date = new Date();
                Session session = cluster.connect();
                // insert Date value into column v, which is a bigint.
                // schema:
                // CREATE TABLE simple.tbl (k int PRIMARY KEY, v bigint)
                PreparedStatement prepared = session.prepare("insert into simple.tbl (k, v) values (?, ?)");
                BoundStatement bound = prepared.bind();
                bound.setInt("k", 0);
                bound.setTimestamp("v", date);
                session.execute(bound);
    
                // Retrieve column v as a Date.
                Row row = session.execute("select v from simple.tbl").one();
                System.out.println(row.getTimestamp("v"));
            } finally {
                cluster.close();
            }
        }
    }
    

答案 2 :(得分:0)

我对这个问题有一个久经考验的解决方案 以下是在Cassandra中插入或检索时间戳的代码

import java.sql.Timestamp;
import com.datastax.driver.core.Session;

SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

Timestamp timeStamp= Timestamp.valueOf(df.format(new Date()));

PreparedStatement ps = session.prepare("SELECT id,time from keySpace.tableName where 
timestamp >=?  order by timestamp allow filtering");

BoundStatement bs = ps.bind(timeStamp);

ResultSet rs = session.execute(bs);

if (rs != null) {
    for (Row row : rs) {
    row.getTimestamp(time);
    row.getString(id);
}}

注意:-session.execute(bs),如果你们想知道这个 session 来自何处,请参考以下链接 How to connect Cassandra using Java class https://stackoverflow.com/a/16871984/9292502