【问题标题】:spring-data-cassandra CassandraTemplate @PrimaryKeyColumn annotation, name property, not working on deletespring-data-cassandra CassandraTemplate @PrimaryKeyColumn 注释,名称属性,不工作删除
【发布时间】:2014-09-08 07:09:52
【问题描述】:

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

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

主键类有 5 个主键列(2 个分区和 3 个集群)。 我的 2 列具有 name 属性,即:

@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;]

以前有人遇到过这个问题吗?

【问题讨论】:

    标签: cassandra cql3 spring-data-cassandra


    【解决方案1】:

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

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

    【讨论】:

    【解决方案2】:

    我和你有同样的问题,我认为我解决的方法对你有用。

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

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

    我的选择、插入操作适用于 spring-data-cassandra,但我的删除操作不能。 然后,spring-data-cassandra参考提供的这一行,不起作用:

    cassandraOperations.delete(category);
    

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

    它抛出一个异常“Unknown Key identifier 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;
    }
    

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

    【讨论】:

      猜你喜欢
      • 2019-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-17
      • 2015-07-03
      • 2016-08-24
      • 2022-01-20
      相关资源
      最近更新 更多