Составной ключ Cassandra с использованием java-драйвера datastax

Я новичок в Cassandra и пытаюсь оценить ее для своей модели. Я тестирую CQL3 и Cassandra 2.0.

Предположим, у меня есть следующая модель предметной области

public class CompositeSample1 {

  private String id;

  private List<ChildT1> childrenT1;

  private List<ChildT2> childrenT2;

  private String rootAttr1;

//getters setters omitted for brevity
}

public class ChildT1 {

  private String key;

  private String attr1;

  private String attr2;
//getters setters omitted for brevity
}

public class ChildT2 {

  private String key;

  private String attrA;

  private String attrB;

//getters setters omitted for brevity
}

Итак, я хочу сохранить указанную выше модель в Cassandra в одной строке с ключом раздела CompositeSample1.id. Дети из двух отношений, которые я хочу сохранить в виде составных столбцов

id, rootAttr1, childT1|1 {attr1, attr2}, childT1|2 {attr1, attr2} .. childT2|1 {attrA, attrB}, childT2|2 {attrA, attrB}..

Я пробовал следующее:

Создал схему со следующим кодом:

session.execute(String.format("CREATE KEYSPACE IF NOT EXISTS %s WITH replication " +
                            "= {'class':'SimpleStrategy', 'replication_factor':3};", DbContext.DATABASE_NAME));

      session.execute("USE "+DbContext.DATABASE_NAME);


      session.execute("CREATE TABLE IF NOT EXISTS compositeSample1 (id uuid, rootAttr1 text, childT1Key text, childT1Attr1 text, , childT1Attr2 text "+
", childT2Key text, childT2AttrA text, childT2AttrB text, PRIMARY KEY ( (id), childT1Key, childT2Key))");

Попытался вставить следующий экземпляр модели

CompositeSample1 compositeSample1 = new CompositeSample1();
    compositeSample1.setId(UUID.randomUUID().toString());
    compositeSample1.setRootAttr1("A380");
    compositeSample1.setChildrenT1(new ArrayList<ChildT1>());
    compositeSample1.setChildrenT2(new ArrayList<ChildT2>());

    for (int i=1;i<10; i++)
    {
      ChildT1 child1 = new ChildT1();
      child1.setKey("childT1|"+i);
      child1.setAttr1("T1_1_"+i);
      child1.setAttr2("T1_2_"+i);
      compositeSample1.getChildrenT1().add(child1);

      ChildT2 child2 = new ChildT2();
      child2.setKey("childT1|"+i);
      child2.setAttrA("T2A"+i);
      child2.setAttrB("T2B"+i);
      compositeSample1.getChildrenT2().add(child2);
    }

    dbContext.createCompositeSample1(compositeSample1);


where the code for createCompositeSample1 is:
public void createCompositeSample1(CompositeSample1 compositeSample1) {
    if (createCompositeSample1 == null)
         createCompositeSample1 = session.prepare("INSERT INTO " + DbContext.DATABASE_NAME + ".compositeSample1(id, childT1Key, childT2Key, rootAttr1) VALUES(?,?,?,?)");

    if (createCompositeSample1ChildT1 == null)
      createCompositeSample1ChildT1 = session.prepare("INSERT INTO " + DbContext.DATABASE_NAME + ".compositeSample1(id, childT1Key, childT2Key, childT1Attr1, childT1Attr2) VALUES(?,?,?,?,?)");


    if (createCompositeSample1ChildT2 == null)
      createCompositeSample1ChildT2 = session.prepare("INSERT INTO " + DbContext.DATABASE_NAME + ".compositeSample1(id, childT1Key, childT2Key, childT2AttrA, childT2AttrB) VALUES(?,?,?,?,?)");
    BoundStatement boundStatementParent = new BoundStatement(createCompositeSample1);

    getSession().execute(boundStatementParent.bind(UUID.fromString(compositeSample1.getId()), null, null, compositeSample1.getRootAttr1()));

    BoundStatement boundStatementChildT1 = new BoundStatement(createCompositeSample1ChildT1);
    for(ChildT1 childT1 : compositeSample1.getChildrenT1()){
      getSession().execute(boundStatementChildT1.bind(UUID.fromString(compositeSample1.getId()), childT1.getKey(), null, childT1.getAttr1(), childT1.getAttr2()));
    }

    BoundStatement boundStatementChildT2 = new BoundStatement(createCompositeSample1ChildT2);
    for(ChildT2 childT2 : compositeSample1.getChildrenT2()){
      getSession().execute(boundStatementChildT2.bind(UUID.fromString(compositeSample1.getId()), null, childT2.getKey(), childT2.getAttrA(), childT2.getAttrB()));
    }
  }

Но я получаю следующую ошибку

com.datastax.driver.core.exceptions.InvalidQueryException: недопустимое нулевое значение для ключевой части кластеризации childt1key

Мои цели:

  1. Чтобы доказать, что я могу вставить CompositeSample1 без дочерних элементов
  2. Добавьте детей к любому из 2 отношений к текущим

Может ли кто-нибудь точно указать, что я делаю неправильно или не понял правильно?

Спасибо


person user3724118    schedule 09.06.2014    source источник
comment
Пожалуйста, попробуйте после изменения части основного ключа сделать следующее   -  person kkmishra    schedule 10.06.2014


Ответы (1)


Вы можете изменить свою часть первичного ключа, нет смысла создавать составной ключ раздела только с одним столбцом (в этом случае у вас есть только столбец id как часть составного ключа раздела), создайте таблицу, как указано ниже.

session.execute("CREATE TABLE IF NOT EXISTS compositeSample1 (id uuid, rootAttr1 text, childT1Key text, childT1Attr1 text, , childT1Attr2 text "+
", childT2Key text, childT2AttrA text, childT2AttrB text, PRIMARY KEY (id, childT1Key, childT2Key))");

И вы можете вставить пустую строку вместо нулевых значений, как показано ниже.

BoundStatement boundStatementParent = new BoundStatement(createCompositeSample1);

        session.execute(boundStatementParent.bind(UUID.fromString(compositeSample1.getId()), StringUtils.EMPTY, StringUtils.EMPTY,
                compositeSample1.getRootAttr1()));

        BoundStatement boundStatementChildT1 = new BoundStatement(createCompositeSample1ChildT1);
        for (ChildT1 childT1 : compositeSample1.getChildrenT1())
        {
            session.execute(boundStatementChildT1.bind(UUID.fromString(compositeSample1.getId()), childT1.getKey(),
                    StringUtils.EMPTY, childT1.getAttr1(), childT1.getAttr2()));
        }

        BoundStatement boundStatementChildT2 = new BoundStatement(createCompositeSample1ChildT2);
        for (ChildT2 childT2 : compositeSample1.getChildrenT2())
        {
            session.execute(boundStatementChildT2.bind(UUID.fromString(compositeSample1.getId()), StringUtils.EMPTY,
                    childT2.getKey(), childT2.getAttrA(), childT2.getAttrB()));
        }

Это должно работать на вас.

person kkmishra    schedule 10.06.2014