使用JDBC驱动程序将UUID插入Cassandra 1.2时出错

时间:2013-05-01 14:47:50

标签: jdbc cassandra

尝试使用JDBC驱动程序将UUID插入Cassandra 1.2时出现异常。这是代码:

UUID uuid = java.util.UUID.randomUUID();
PreparedStatement statement = c.prepareStatement("insert into tree (tree_id) values (?)");
statement.setObject(1, uuid);
statement.execute();

以下是我得到的例外情况:

java.sql.SQLNonTransientException: encountered object of class: class java.util.UUID, but only 'String' is supported to map to the various VARCHAR types
        at org.apache.cassandra.cql.jdbc.HandleObjects.makeBadMapping(HandleObjects.java:124)
        at org.apache.cassandra.cql.jdbc.HandleObjects.makeBytes(HandleObjects.java:391)
        at org.apache.cassandra.cql.jdbc.CassandraPreparedStatement.setObject(CassandraPreparedStatement.java:351)
        at org.apache.cassandra.cql.jdbc.CassandraPreparedStatement.setObject(CassandraPreparedStatement.java:338)
        at CassandraTest.main(CassandraTest.java:26)

这是我的架构:

CREATE TABLE browse.tree (tree_id UUID PRIMARY KEY, activation_time TIMESTAMP, tree_lock_id INT, sql_publication_id INT);

有点奇怪,它认为我的UUID字段是VARCHAR。任何帮助将不胜感激。谢谢!

3 个答案:

答案 0 :(得分:2)

UUID不是java.sql.Types规范的一部分。我的阅读是,正确的行为将是驱动程序抛出SQLException。或者,它可以稍微弯曲规则并接受它。

作为一种解决方法,uuid的字符串表示应该可以工作,但我真的建议使用native CQL driver而不是JDBC。您将不会遇到任何这些规范不匹配,并且它在处理故障转移和负载平衡等方面做得更好。

答案 1 :(得分:0)

您可以使用模式内省来解决此限制。

我的表:

CREATE TABLE TEST_KEY(pk uuid,text varchar,primary key(pk));

我的反省:

package org.apache.cassandra.cql.jdbc;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
import java.util.UUID;


public class CassandraPS {

   private PreparedStatement ps;

   public CassandraPS(PreparedStatement ps) {
      this.ps = ps;
   }

   public void setUUID(int parameterIndex, UUID uuid) throws SQLException {
      CassandraPreparedStatement psCas = (CassandraPreparedStatement) ps;
      psCas.setObject(parameterIndex, JdbcUUID.instance.decompose(uuid).array(),
      Types.LONGVARBINARY);
   }
}

我的道:

....... DAO ..........
public void insert(UUID pk, String text) throws SQLException {
   String cql = "insert into my_ks.test_key(pk, text) values(?,?)";
   PreparedStatement ps = null;
   try {
      ps = conn.prepareStatement(cql);
      new CassandraPS(ps).setUUID(1, pk);
      ps.setString(2, text);
      ps.executeUpdate();
    } finally {
       if (ps != null) {
         ps.close();
    }
  }
}
...

我的司机: 卡桑德拉-JDBC-1.2.5.jar

Gilberto Vieira da Silva

答案 2 :(得分:0)

吉尔伯托是对的。使用这个功能:

printf

将uuid转换为字节数组,然后ps.setObject(index,byte_array,Types.VARBINARY)也可以正常工作