我正在使用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;]
之前有没有人遇到过这个问题?
答案 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;
}
我希望它有所帮助!!我知道它可以更好地解决,所以...任何评论都应该被赞赏。