【问题标题】:Cassandra throwing CodecNotFoundException [bigint <-> java.util.Date]Cassandra 抛出 CodecNotFoundException [bigint <-> java.util.Date]
【发布时间】:2019-10-30 17:56:07
【问题描述】:

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

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

你能帮我解决 cassandra 抛出的异常并解决这个问题吗?

【问题讨论】:

    标签: cassandra


    【解决方案1】:

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

    使用getTime() 方法获取以毫秒为单位的时间,这对于插入 bigint 列来说很长。

    例子:

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

    使用timeInMilis插入cassandra

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

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

    更多关于 CQL - Java 映射:https://docs.datastax.com/en/developer/java-driver/3.1/manual/#cql-to-java-type-mapping

    【讨论】:

    【解决方案2】:

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

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

    1. 将列类型更改为映射到java.util.Datetimestamp(并通过setTiemstamp/getTimstamp 设置/访问)。
    2. setLongDate.getTime() 结合使用,将Date 转换为代表纪元毫秒的long
    3. 创建并注册一个将java.util.Date 映射到bigintcustom codec,即:
    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();
            }
        }
    }
    

    【讨论】:

    • 我刚刚注意到你提到了“java实体”,如果这意味着你正在使用映射模块,如果你像我描述的那样创建编解码器并在创建映射器之前注册它,这也适用于映射器。
    【解决方案3】:

    我有一个久经考验的解决方案来解决这个问题 以下是在 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

    【讨论】:

      猜你喜欢
      • 2016-10-02
      • 2019-11-28
      • 2015-05-18
      • 1970-01-01
      • 2018-11-06
      • 2018-06-08
      • 2022-08-22
      • 2020-05-08
      • 2013-11-15
      相关资源
      最近更新 更多