Perché cassandra lanciando com.datastax.driver.core.exceptions.invalidqueryexception: Definizioni multiple trovate per colonna

StackOverflow https://stackoverflow.com//questions/25084210

  •  02-01-2020
  •  | 
  •  

Domanda

Context :

Sto usando un test di Junit in Eclipse utilizzando Cassandra incorporato per testare la mia classe DAO che utilizza un client ASTYANAX configurato per JavaDriver.Quando l'istanza dell'oggetto DAO inserisce in Cassandra, sto ottenendo questa eccezione com.datastax.driver.core.exceptions.invalidqueryexception: definizioni multiple trovate per colonna ..ColumnName

TestClass

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();
    }
}
.

classe sotto test

@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);
        }
    }

}
.

È stato utile?

Soluzione

Quando il driver Java lancia un InvalidQueryException, è un errore di un errore da Cassandra.L'errore "Definizioni multiple trovate per colonna ..." indica che una colonna viene menzionata più di una volta in un'istruzione di aggiornamento.Puoi simularlo in 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"
.

Non ho familiarità con Astyanax, ma la mia ipotesi è che aggiunge già l'ID alla query quando si chiama withRow, quindi non è necessario aggiungerlo di nuovo con putColumn.Prova a rimuovere quella chiamata (seconda riga in campione riformattato di seguito):

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top