如何解决Datastax java驱动程序4中的严格列检查导致问题
下面是我们的实体类
@Entity(defaultKeyspace = CASSANDRA_KEYSPACE)
@CqlName(CASSANDRA_TABLE)
public static class Scientist implements Serializable {
@CqlName("person_name")
public String name;
@Computed("writetime(person_name)")
@CqlName("name_ts")
public Long nameTs;
@CqlName("person_id")
@PartitionKey
public Integer id;
public Scientist() {}
public Scientist(int id,String name) {
super();
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return id + ":" + name;
}
@Override
public boolean equals(@Nullable Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Scientist scientist = (Scientist) o;
return id.equals(scientist.id) && Objects.equal(name,scientist.name);
}
@Override
public int hashCode() {
return Objects.hashCode(name,id);
}
}
@Dao
public interface ScientistDao {
@GetEntity
MappedAsyncPagingIterable<Scientist> map(AsyncResultSet resultSet);
@Delete
CompletionStage<Void> deleteAsync(Scientist entity);
@Insert
CompletionStage<Void> saveAsync(Scientist entity);
}
面临的问题是,当计算字段(在上述情况下 writetime(person_name) )未被选择作为查询的一部分时,映射失败。
在 3.x 驱动程序中:忽略 ResultSet 中不存在的映射字段。 link
在 4.x 驱动程序中:对于每个实体字段,数据库表或 UDT 必须包含具有对应名称的列。 link
请提出一个可能的解决方案/变通方法,在这种情况下,此计算字段可以根据需要成为查询的一部分,并且映射成功发生而不会引发 IllegalArgumentException。
编辑:
科学家表架构
CREATE TABLE beam_ks.scientist (person_id int PRIMARY KEY,person_name text);
以下是尝试的查询:
select person_id,writetime(person_name) as name_ts from beam_ks.scientist where person_id=10
Caused by: java.lang.IllegalArgumentException: person_name is not a column in this row
at com.datastax.oss.driver.internal.core.cql.DefaultRow.firstIndexOf(DefaultRow.java:110)
at com.datastax.oss.driver.api.core.data.GettableByName.get(GettableByName.java:144)
at org.apache.beam.sdk.io.cassandra.CassandraIOTest_ScientistHelper__MapperGenerated.get(CassandraIOTest_ScientistHelper__MapperGenerated.java:89)
CassandraIOTest_ScientistHelper__MapperGenerated 中的获取方法:
@Override
public CassandraIOTest.Scientist get(GettableByName source) {
CassandraIOTest.Scientist returnValue = new CassandraIOTest.Scientist();
Integer propertyValue = source.get("person_id",Integer.class);
returnValue.setId(propertyValue);
String propertyValue1 = source.get("person_name",String.class);
returnValue.setName(propertyValue1);
return returnValue;
}
另外,documentation 没有指定是否为计算值添加 getter 和 setter 方法。因此,它们从实体类中移除
解决方法
使用 @GetEntity
方法时,您有责任提供与实体定义 100% 兼容的结果集对象。
此处您的 Scientist
实体包含两个常规字段:person_id
(整数)和 person_name
(文本)。因此,您的结果集必须(至少)包含具有这些名称和类型的两列。
但您说您提供了以下查询:select person_id,writetime(person_name) as name_ts from beam_ks.scientist where person_id=10
。
此查询不包含所需的列。您应该将查询更改为以下查询或类似内容:
select person_id,person_name from beam_ks.scientist where person_id=10
请注意,@GetEntity
方法不识别计算值,只能识别常规值。没有必要包含 writetime(person_name) as name_ts
,它无论如何都不会被映射。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。