Kundera-Cassandra未能使用MappedSuperClass映射实体的复合键

时间:2016-06-03 16:13:44

标签: java jpa cassandra kundera

我正在努力映射两个表,而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中正确构建令牌方法签名以进行分页,因为我的模型不再符合对该功能的期望)。

2 个答案:

答案 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@MappedSuperClassStagingRecord的{​​{1}}。但是,我将ProductionRecordClusteringKey合并为一个包含所有字段的类,从而修复了映射问题。

不幸的是,这意味着我无法利用Kundera的分页功能,因为生成的CQL的PartitionKey函数只能使用单个参数生成,而不是全部11(这是设计中的模型,问题应该导致正确的CQL输出。)

最终,我通过NativeQueries和token()函数自己实现了分页,手动插入所有必需的字段。