spring-data-cassandra CassandraTemplate @PrimaryKeyColumn注释,name属性,不用于删除

时间:2014-07-17 12:06:01

标签: cassandra cql3 spring-data-cassandra

我正在使用spring-data-cassandra模块。

我有一个使用@Table注释的注释bean和一个使用@PrimaryKeyClass

的主类

主键类有5个主键列(2个分区,3个分组)。 我的2列中有名称属性,即:。

@PrimaryKeyColumn(name="correlated_type", ordinal = 2, type= PrimaryKeyType.CLUSTERED)
private String correlatedType;

使用CassandraTemplate插入操作时,一切正常 但是当我使用cassandraTemplate.deleteAsynchronously(List<entities> list)时,列名称不会使用name属性进行解析,而是保留字段名称。

我尝试对单个对象使用常规删除操作,并尝试使用forceQuote = true属性都没有帮助。

insert log sample:
[o.s.cassandra.core.CqlTemplate]     asynchronously executing [INSERT INTO identity_correlations(type,value,"**correlated_type**",ts,"**correlated_value**",extra) VALUES ('Participant','p5','Visitor',4,'R3',{'v':'1','labels':'b,c'}) USING TTL 34128000;

delete log sample:
[o.s.cassandra.core.CqlTemplate]     asynchronously executing [BEGIN BATCH DELETE  FROM identity_correlations WHERE **correlatedValue**='p5' AND **correlatedType**='Participant' AND type='Visit' AND value='v1' AND ts=1;DELETE  FROM identity_correlations WHERE correlatedValue='R3' AND correlatedType='Visitor' AND type='Participant' AND value='p5' AND ts=4;DELETE  FROM identity_correlations WHERE correlatedValue='R3' AND correlatedType='Visitor' AND type='Participant' AND value='p5' AND ts=3;APPLY BATCH;]

之前有没有人遇到过这个问题?

2 个答案:

答案 0 :(得分:1)

跟踪https://jira.spring.io/browse/DATACASS-142

讨论在https://groups.google.com/forum/#!forum/spring-data-cassandra(我们正在考虑放弃支持stackoverflow.com)。

答案 1 :(得分:1)

我和你有同样的问题,我认为我解决的方式可以为你效劳。

我有一个使用@PrimaryKeyColumn注释的Category.java类。

@PrimaryKeyColumn(name = "language_id", ordinal = 1, type = PrimaryKeyType.PARTITIONED)
private String languageId;

我的select,insert操作适用于spring-data-cassandra,但我的删除操作没有。 然后,spring-data-cassandra引用提供的这行不起作用:

cassandraOperations.delete(category);

http://docs.spring.io/spring-data/cassandra/docs/1.2.0.RC1/reference/html/

它抛出异常“未知密钥标识符languageId”。

生成的内部CQL语句如下:

DELETE FROM categories WHERE id='sdffsd' AND languageId='EN';

然后您可以看到列的名称生成错误。

我的Category.java类如下:

package com.ehub.hmap.db.entities;

import org.springframework.cassandra.core.PrimaryKeyType;
import org.springframework.data.cassandra.mapping.Column;
import org.springframework.data.cassandra.mapping.PrimaryKeyColumn;
import org.springframework.data.cassandra.mapping.Table;

@Table(value = "categories")
public class Category {

    @PrimaryKeyColumn(name = "id", ordinal = 0, type = PrimaryKeyType.PARTITIONED)
    private String id;

    @PrimaryKeyColumn(name = "language_id", ordinal = 1, type = PrimaryKeyType.PARTITIONED)
    private String languageId;

    @Column
    private String description;

    @Column
    private String tooltip;

    public Category(String id, String languageId, String description,
        String tooltip) {
        this.id = id;
        this.languageId = languageId;
        this.description = description;
        this.tooltip = tooltip;
    }

   public String getId() {
       return id;
   }

   public String getLanguageId() {
       return languageId;
   }

   public String getDescription() {
       return description;
   }

   public String getTooltip() {
       return tooltip;
   }

}

我从Jersey REST方法开始详细说明我的解决方案。

@POST
@Path("/deleteCategory")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces(MediaType.APPLICATION_JSON)
public Response deleteCategory(Category category) {

    dataManager.deleteEntity(Category.class, category);

    return Response.ok().build();
}

在我的DataManager.java类中,我有:

/**
 * Delete an entity at DB
 * 
 * @param entity: T type object
 * @return
 */
public <T> void deleteEntity(Class<T> typedClass, T entity) {

    // Start building the query
    Delete delete = QueryBuilder.delete().from(CassandraUtil.getTableName(typedClass));

    // Get a map<key,value> where key is the Db column name and value is the model name
    Map<String, String> map = CassandraUtil.getTableKeyMap(typedClass);

    for (Map.Entry<String, String> entry : map.entrySet())
    {
        // getKey() has the DB name, and getValue() has the model name
        delete.where(QueryBuilder.eq(entry.getKey(), CassandraUtil.getPropertyValue(entity, entry.getValue())));
    }
    cassandraOperations.execute(delete);
}

在我的CassandraUtil.java,我有:

/**
 * Gets a <key,value> map where each key is the name of the column at Db and
 * value is the name of the field at your model.
 * 
 * @param Annotated Typed class corresponding to your entity model.
 * @return Map with Db column name and Model name.
 */
public static <T> Map<String,String> getTableKeyMap(Class<T> typedClass) {

    Map<String, String> map = new HashMap<String, String>();

    if (typedClass != null)
    {
        Field[] fields = typedClass.getDeclaredFields();

        for (Field field : fields) {

            try {
                String dbName = null;

                field.setAccessible(true);

                // Checks PrimaryKeyColumn annotation
                PrimaryKeyColumn pkc = field.getAnnotation(PrimaryKeyColumn.class);

                if (pkc != null)
                {
                    dbName = (pkc.name() != null) ? pkc.name(): field.getName();

                    // dbName gets the name of the column in Db
                    // getName() obtains the name in our model
                    map.put(dbName, field.getName());
                }
                // Checks PrimaryKey annotation
                PrimaryKey pk = field.getAnnotation(PrimaryKey.class);

                if (pk != null)
                {
                    dbName = (pk.value() != null) ? pk.value(): field.getName();

                    // dbName gets the name of the column in Db
                    // getName() obtains the name in our model
                    map.put(dbName, field.getName());
                }

            } catch (IllegalArgumentException
                    | SecurityException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }
    return map;
}

public static <T> String getPropertyValue(T obj, String name) {
    String str = null;

    if (name != null)
    {
        try
        {
            Class<T> objClass = (Class<T>) obj.getClass();
            Field field = objClass.getDeclaredField(name);
            field.setAccessible(true);
            String val = field.get(obj) != null ? field.get(obj).toString(): "";

            return val;

        }

        catch (Exception iEx) {
        }

    }
    return str;
}

我希望它有所帮助!!我知道它可以更好地解决,所以...任何评论都应该被赞赏。