繁体   English   中英

为什么 Cassandra 抛出 com.datastax.driver.core.exceptions.InvalidQueryException:为列找到多个定义

[英]Why Cassandra throwing com.datastax.driver.core.exceptions.InvalidQueryException: Multiple definitions found for column

上下文

I am running a jUnit test in eclipse by using embedded Cassandra to test my DAO class which is using an Astyanax client configured for JavaDriver. 当 DAO object 实例插入 Cassandra 时,我收到此异常 com.datastax.driver.core.exceptions.InvalidQuerynameException: Multiple definitions found for column.column

测试类

public class LeaderBoardDaoTest {

    private static LeaderBoardDao   dao;
    public static CassandraCQLUnit  cassandraCQLUnit;

    private String                  hostIp  = "127.0.0.1";
    private int                     port    = 9142;
    public Session                  session;
    public Cluster                  cluster;

    @BeforeClass
    public static void startCassandra() throws IOException, TTransportException, ConfigurationException, InterruptedException {
        System.setProperty("archaius.deployment.applicationId", "leaderboardapi");
        System.setProperty("archaius.deployment.environment", "test");

        EmbeddedCassandraServerHelper.startEmbeddedCassandra("cassandra.yaml");
        // cassandraCQLUnit = new CassandraCQLUnit(new
        // ClassPathCQLDataSet("simple.cql", "lbapi"), "cassandra.yaml");
        Injector injector = Guice.createInjector(new TestModule());
        dao = injector.getInstance(LeaderBoardDao.class);

    }

    @Before
    public void load() {
        cluster = new Cluster.Builder().withClusterName("leaderboardcassandra").addContactPoints(hostIp).withPort(port).build();
        session = cluster.connect();
        CQLDataLoader dataLoader = new CQLDataLoader(session);
        dataLoader.load(new ClassPathCQLDataSet("simple.cql", "lbapi"));
        session = dataLoader.getSession();
    }


    @Test
    public void test() {
        ResultSet result = session.execute("select * from mytable WHERE id='myKey01'");
        Assert.assertEquals(result.iterator().next().getString("value"), "myValue01");
    }

    @Test
    public void testInsert() {
        LeaderBoard lb = new LeaderBoard();
        lb.setName("name-1");
        lb.setDescription("description-1");
        lb.setActivityType(ActivityType.FUEL);
        lb.setImage("http:/");
        lb.setLbId(UUID.fromString("3F2504E0-4F89-41D3-9A0C-0305E82C3301"));
        lb.setStartTime(new Date());
        lb.setEndTime(new Date());
        dao.insert(lb);
        ResultSet resultSet = session.execute("select * from leaderboards WHERE leaderboardid='3F2504E0-4F89-41D3-9A0C-0305E82C3301'");
    }

    @After
    public void clearCassandra() {
        EmbeddedCassandraServerHelper.cleanEmbeddedCassandra();
    }

    @AfterClass
    public static void stopCassandra() {
        EmbeddedCassandraServerHelper.stopEmbeddedCassandra();
    }
}

Class 被测

@Singleton
public class LeaderBoardDao {

    private static final Logger                 log                 = LoggerFactory.getLogger(LeaderBoardDao.class);

    @Inject
    private AstyanaxMutationsJavaDriverClient   client;

    private static final String                 END_TIME            = "end_time";
    private static final String                 START_TIME          = "start_time";
    private static final String                 IMAGE               = "image";
    private static final String                 ACTIVITY_TYPE       = "activity_type";
    private static final String                 DESCRIPTION         = "description";
    private static final String                 NAME                = "name";
    private static final String                 LEADERBOARD_ID      = "leaderboardID";
    private static final String                 COLUMN_FAMILY_NAME  = "leaderboards";

    private ColumnFamily<UUID, String>          cf;

    public LeaderBoardDao() throws ConnectionException {
        cf = ColumnFamily.newColumnFamily(COLUMN_FAMILY_NAME, UUIDSerializer.get(), StringSerializer.get());
    }

    /**
     * Writes the Leaderboard to the database.
     * 
     * @param lb
     */
    public void insert(LeaderBoard lb) {
        try {
            MutationBatch m = client.getKeyspace().prepareMutationBatch();
            cf.describe(client.getKeyspace());
            m.withRow(cf, lb.getLbId()).putColumn(LEADERBOARD_ID, UUIDUtil.asByteArray(lb.getLbId()), null).putColumn(NAME, lb.getName(), null).putColumn(DESCRIPTION, lb.getDescription(), null)
                    .putColumn(ACTIVITY_TYPE, lb.getActivityType().name(), null).putColumn(IMAGE, lb.getImage()).putColumn(START_TIME, lb.getStartTime()).putColumn(END_TIME, lb.getEndTime());

            m.execute();
        } catch (ConnectionException e) {
            Throwables.propagate(e);
        }
    }

    /**
     * Reads leaderboard from database
     * 
     * @param id
     * @return {@link LeaderBoard}
     */
    public LeaderBoard read(UUID id) {
        OperationResult<ColumnList<String>> result;
        LeaderBoard lb = null;
        try {
            result = client.getKeyspace().prepareQuery(cf).getKey(id).execute();

            ColumnList<String> cols = result.getResult();
            if (!cols.isEmpty()) {
                lb = new LeaderBoard();
                lb.setLbId(cols.getUUIDValue(LEADERBOARD_ID, null));
                lb.setName(cols.getStringValue(NAME, null));
                lb.setActivityType(ActivityType.valueOf(cols.getStringValue(ACTIVITY_TYPE, null)));
                lb.setDescription(cols.getStringValue(DESCRIPTION, null));
                lb.setEndTime(cols.getDateValue(END_TIME, null));
                lb.setStartTime(cols.getDateValue(START_TIME, null));
                lb.setImage(cols.getStringValue(IMAGE, null));
            } else {
                log.warn("read: is empty: no record found for " + id);
            }

            return lb;
        } catch (ConnectionException e) {
            log.error("failed to read from C*", e);
            throw new RuntimeException("failed to read from C*", e);
        }
    }

}

当 Java 驱动程序抛出InvalidQueryException时,它会重新抛出来自 Cassandra 的错误。 错误“为列找到多个定义...”表示在更新语句中多次提及某个列。 你可以在cqlsh中模拟它:

cqlsh> create table test(i int primary key);
cqlsh> insert into test (i, i) values (1, 2);
code=2200 [Invalid query] message="Multiple definitions found for column i"

我对 Astyanax 不熟悉,但我的猜测是,当您调用withRow时,它已经将 id 添加到查询中,因此您无需使用putColumn再次添加它。 尝试删除该调用(下面重新格式化示例中的第二行):

m.withRow(cf, lb.getLbId())
 .putColumn(LEADERBOARD_ID, UUIDUtil.asByteArray(lb.getLbId()), null)
 ... // other putColumn calls

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM