插入UUID时出错';使用JDBC驱动程序将其转换为Cassandra 1.2

插入UUID时出错';使用JDBC驱动程序将其转换为Cassandra 1.2,jdbc,cassandra,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.

我在尝试使用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。任何帮助都将不胜感激。谢谢

UUID不是java.sql.Types规范的一部分。我的理解是,正确的行为应该是驱动程序抛出SQLException。或者,它可以稍微改变规则,无论如何都接受它


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

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

我的桌子:

创建表TEST_键(pk uuid、text varchar、主键(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();
    }
  }
}
...
我的司机: cassandra-jdbc-1.2.5.jar


吉尔伯托·维埃拉·达席尔瓦是对的。使用此功能:

public static byte[] uuid2ByteArray(java.util.UUID uuid) {
    long msb = uuid.getMostSignificantBits();
    long lsb = uuid.getLeastSignificantBits();
    byte[] buffer = new byte[16];

    for (int i = 0; i < 8; i++) {
        buffer[i] = (byte) (msb >>> 8 * (7 - i));
    }
    for (int i = 8; i < 16; i++) {
        buffer[i] = (byte) (lsb >>> 8 * (7 - i));
    }

    return buffer;
}
公共静态字节[]uuid2ByteArray(java.util.UUID UUID){
long msb=uuid.getMostSignificantBits();
long lsb=uuid.getLeastSignificantBits();
字节[]缓冲区=新字节[16];
对于(int i=0;i<8;i++){
缓冲区[i]=(字节)(msb>>>8*(7-i));
}
对于(int i=8;i<16;i++){
缓冲区[i]=(字节)(lsb>>>8*(7-i));
}
返回缓冲区;
}

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

谢谢,但字符串表示法也不起作用。说它需要正好是16个字节。字节[]也不起作用(与UUID的错误相同)。UUID是最重要的类型之一,我很难看到它是如何被完全打破的。我将研究本机CQL驱动程序。正如Jonathan所说,尝试使用本机CQL驱动程序。关于生成UUID值的更多信息,请参见cassandra FAQ,如何生成UUID,这里给出了一个很好的描述