我正在努力映射两个表,而Cassandra的差异很小,但Kundera未能正确映射我的模型(我已将其配置为在EntityManager创建时验证对表的映射)。给定以下复合密钥(根据these directions, since paging is desired结构化并另外使用Datastax Driver:
CQL表创建的两个表都具有以下主键:
PRIMARY KEY ((key1, key2, key3, key4, key5, key6, key7, key8, key9, key10, key11), "clusteringKey")
PartitionKey:
@Embeddable
public class PartitionKey {
@Column
private key1
//repeat for 11 more keys
}
ClusteringKey:
@Embeddable
public class ClusteringKey {
@Embedded
private PartitionKey key;
@Column
private UUID clusteringKey;
}
CQL3的属性加载:
public static EntityManagerFactory getEntityManagerFactory() throws IOException {
if(entityManagerFactory == null) {
entityManagerFactory = Persistence.createEntityManagerFactory("cassandra_pu",getProperties());
}
return entityManagerFactory;
}
public static Properties getProperties() throws IOException {
if(properties == null) {
properties = new Properties();
properties.load(Application.class.getResourceAsStream("/application.properties"));
properties.put(CassandraConstants.CQL_VERSION, CassandraConstants.CQL_VERSION_3_0);
}
return properties;
}
到目前为止,我尝试过两种型号。
第一种情况:
SuperRecord:
@MappedSuperClass
public abstract class SuperRecord {
@EmbeddedId
private ClusteringKey clusteringkey;
//Additional Fields
}
//extended by StagingRecord, ProductionRecord
当ClusteringKey本身正确映射时,根本没有任何与PartitionKey相关的映射。
在我的第二次尝试中:
SuperRecord:
@MappedSuperClass
public abstract class SuperRecord {
//Common fields excluding keys
}
StagingRecord:
@Entity
public class StagingRecord extends SuperRecord {
@EmbeddedId
private ClusteringKey key;
}
ProductionRecord:
@Entity
public class ProductionRecord extends SuperRecord {
@EmbeddedId
private ClusteringKey key;
@Column(name="solr_query")
private String solrQuery;
}
在此尝试中,当我的聚类键映射时,我的partitionkey映射为单个二进制对象,而不是其所需的组成列。
什么阻止我的PartitionKey进行适当的映射,以及如何解决?
编辑:
分发超类字段后,我发现@MappedSuperclass
不是我问题的一个因素;只有嵌套的@Embeddeds
。另外,如果我要合并PartitionKey和ClusteringKey类,映射将通过验证(尽管它将无法在生成的CQL中正确构建令牌方法签名以进行分页,因为我的模型不再符合对该功能的期望)。
答案 0 :(得分:3)
我尝试使用下面的第一个模型。
<强> PartitionKey:强>
@Embeddable
public class PartitionKey {
@Column
private String key1;
@Column
private String key2;
@Column
private String key3;
//setters and getters
}
<强> ClusteringKey:强>
@Embeddable
public class ClusteringKey {
@Embedded
private PartitionKey key;
@Column
private UUID clusteringKey;
//setters and getters
}
<强> SuperRecord:强>
@MappedSuperclass
public abstract class SuperRecord
{
@EmbeddedId
private ClusteringKey clusteringkey;
private String additionColumn;
//setters and getters
}
<强> ProductionRecord:强>
@Entity
public class ProductionRecord extends SuperRecord {
@Column(name="solr_query")
private String solrQuery;
//setters and getters
}
测试用例的有用部分:
Map<String, String> props = new HashMap<>();
props.put(CassandraConstants.CQL_VERSION, CassandraConstants.CQL_VERSION_3_0);
emf = Persistence.createEntityManagerFactory("cass_pu", props);
ProductionRecord pr = new ProductionRecord();
pr.setSolrQuery("some solr query");
pr.setAdditionColumn("col1");
ClusteringKey ck = new ClusteringKey();
ck.setClusteringKey(UUID.randomUUID());
PartitionKey pk = new PartitionKey();
pk.setKey1("k1");
pk.setKey2("k2");
pk.setKey3("k3");
ck.setKey(pk);
pr.setClusteringkey(ck);
em.persist(pr);
它工作正常。
确保您启用了CQL3。
答案 1 :(得分:0)
我在截止日期前跑了,所以我发现自己正在实施分页;该模型最终采用了问题中最初所述的形式:SuperRecord
是@MappedSuperClass
和StagingRecord
的{{1}}。但是,我将ProductionRecord
和ClusteringKey
合并为一个包含所有字段的类,从而修复了映射问题。
不幸的是,这意味着我无法利用Kundera的分页功能,因为生成的CQL的PartitionKey
函数只能使用单个参数生成,而不是全部11(这是设计中的模型,问题应该导致正确的CQL输出。)
最终,我通过NativeQueries和token()函数自己实现了分页,手动插入所有必需的字段。