I have declared primary using PartitionKey annotation but still getting Entity Order does not declare a primary key

huangapple go评论96阅读模式
英文:

I have declared primary using PartitionKey annotation but still getting Entity Order does not declare a primary key

问题

我有以下的POJO:

@Entity
public class Order {    
    
    @Column(name = "id")
    @PartitionKey
    private String id;

    @Column(name = "customer_id")
    private String customerId;

    @Column(name = "loyalty_id")
    private String loyaltyId;

    @Column(name = "customer_email")
    private String customerEmail;

    public Order() {

    }
    public String getId() {
       return id;
    }

    public void setId(String id) {
        this.id = id;
    }
    // 其他的 getter 和 setter 方法
}

在以下代码处出现异常:

CqlSession session = CqlSession.builder().build();
OrderMapper mapper = new OrderMapperBuilder(session).build();
orderDao = mapper.orderDao(CqlIdentifier.fromCql(connectionManager.getSession().getLoggedKeyspace()));

connectionManager 的定义在这里:https://pastebin.com/b3GKJuV6

异常如下:

Entity Order does not declare a primary key
com.datastax.oss.driver.api.mapper.MapperException: Entity Order does not declare a primary key
    at com.datastax.oss.driver.api.mapper.MapperException.copy(MapperException.java:44)
    at com.datastax.oss.driver.internal.core.util.concurrent.CompletableFutures.getUninterruptibly(CompletableFutures.java:149)
    ...

我按照这里的文档进行实现:https://docs.datastax.com/en/developer/java-driver/4.2/manual/mapper/。可能的原因是什么呢?

编辑:- 添加模式定义:

CREATE TABLE order_keyspace.order (
    id text PRIMARY KEY,
    customer_email text,
    customer_id text,
    loyalty_id text
) WITH bloom_filter_fp_chance = 0.01
    AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'}
    AND comment = ''
    AND compaction = {'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold': '32', 'min_threshold': '4'}
    AND compression = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'}
    AND crc_check_chance = 1.0
    AND dclocal_read_repair_chance = 0.1
    AND default_time_to_live = 0
    AND gc_grace_seconds = 864000
    AND max_index_interval = 2048
    AND memtable_flush_period_in_ms = 0
    AND min_index_interval = 128
    AND read_repair_chance = 0.0
    AND speculative_retry = '99PERCENTILE';
英文:

I have the following POJO:

@Entity
public class Order {    
    
    @Column(name = "id")
    @PartitionKey
    private String id;

    @Column(name = "customer_id")
    private String customerId;

    @Column(name = "loyalty_id")
    private String loyaltyId;

    @Column(name = "customer_email")
    private String customerEmail;

    public Order() {

    }
    public String getId() {
       return id;
    }

    public void setId(String id) {
        this.id = id;
    }
    ... getters and setters
}

Getting the exception at the following code:

	        CqlSession session = CqlSession.builder().build();
	        OrderMapper mapper = new OrderMapperBuilder(session).build();
	        orderDao = mapper.orderDao(CqlIdentifier.fromCql(connectionManager.getSession().getLoggedKeyspace()));

The definition of connectionManager is here: https://pastebin.com/b3GKJuV6

The exception is as:

	Entity Order does not declare a primary key
	com.datastax.oss.driver.api.mapper.MapperException: Entity Order does not declare a primary key
		at com.datastax.oss.driver.api.mapper.MapperException.copy(MapperException.java:44)
		at com.datastax.oss.driver.internal.core.util.concurrent.CompletableFutures.getUninterruptibly(CompletableFutures.java:149)
	...

I am implementing by following the documentation here: https://docs.datastax.com/en/developer/java-driver/4.2/manual/mapper/ . What could be the possible cause of this?

EDIT:- Adding the schema definition:

	CREATE TABLE order_keyspace.order (
	    id text PRIMARY KEY,
	    customer_email text,
	    customer_id text,
	    loyalty_id text
	) WITH bloom_filter_fp_chance = 0.01
	    AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'}
	    AND comment = ''
	    AND compaction = {'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold': '32', 'min_threshold': '4'}
	    AND compression = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'}
	    AND crc_check_chance = 1.0
	    AND dclocal_read_repair_chance = 0.1
	    AND default_time_to_live = 0
	    AND gc_grace_seconds = 864000
	    AND max_index_interval = 2048
	    AND memtable_flush_period_in_ms = 0
	    AND min_index_interval = 128
	    AND read_repair_chance = 0.0
	    AND speculative_retry = '99PERCENTILE';

答案1

得分: 2

完整编辑:

这里有几件事情让我感到困惑,唯一我能够复现错误的方法是破坏了 getter/setter,而这在你的代码中似乎没有问题,但是存在一些剪贴板转换的情况。目前我能够看到的情况如下:

  • 使用了 @Column(name = "id") - 这不是 com.datastax.oss.driver.api.mapper.annotations 中的一个注解。应该使用 @CqlName。
  • 为表使用了保留关键字 - "order" 是一个保留关键字,我非常确定这会在代码中造成相当大的混淆,尽管当我尝试将该关键字作为表名与映射器一起使用时,会得到不同的错误。我认为你应该将这个表命名为其他名称,避免使用该关键字。

注解链接:
https://docs.datastax.com/en/developer/java-driver/4.2/manual/mapper/entities/ 包含了规则/可用的注解,你可以在这里看到如何使用 @CqlName 来告知映射器 Cassandra 列名,如果它与命名约定不同。

我相信你在之前的问题中使用的是 4.2 驱动程序,但如果升级到了 4.7(推荐),则链接如下:https://docs.datastax.com/en/developer/java-driver/4.7/manual/mapper/entities/)

以下代码已经正常工作:

CQL:

CREATE TABLE customer_orders (
    id text PRIMARY KEY,
    customer_email text,
    customer_id text,
    loyalty_id text
);

insert into customer_orders (id, customer_email, customer_id, loyalty_id) values ('a','a@b.c.com', '1234', '5678');

POJO(普通 Java 对象):

import com.datastax.oss.driver.api.mapper.annotations.CqlName;
import com.datastax.oss.driver.api.mapper.annotations.Entity;
import com.datastax.oss.driver.api.mapper.annotations.PartitionKey;

@Entity
public class CustomerOrders {
    @CqlName("id")
    @PartitionKey
    private String id;

    @CqlName("customer_id")
    private String customerId;

    @CqlName("loyalty_id")
    private String loyaltyId;

    @CqlName("customer_email")
    private String customerEmail;

    public CustomerOrders() {

    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getCustomerId() {
        return customerId;
    }

    public void setCustomerId(String customerId) {
        this.customerId = customerId;
    }

    public String getLoyaltyId() {
        return loyaltyId;
    }

    public void setLoyaltyId(String loyaltyId) {
        this.loyaltyId = loyaltyId;
    }

    public String getCustomerEmail() {
        return customerEmail;
    }

    public void setCustomerEmail(String customerEmail) {
        this.customerEmail = customerEmail;
    }
}

DaoMapper:

import com.datastax.oss.driver.api.core.CqlIdentifier;
import com.datastax.oss.driver.api.mapper.annotations.*;

@Mapper
public interface DaoMapper {

    @DaoFactory
    OrderDao orderDao(@DaoKeyspace CqlIdentifier keyspace);
}

OrderDao:

import com.datastax.oss.driver.api.mapper.annotations.Dao;
import com.datastax.oss.driver.api.mapper.annotations.Delete;
import com.datastax.oss.driver.api.mapper.annotations.Insert;
import com.datastax.oss.driver.api.mapper.annotations.Select;

@Dao
public interface OrderDao {

    @Select
    CustomerOrders findById(String id);

    @Insert
    void save(CustomerOrders order);

    @Delete
    void delete(CustomerOrders order);
}

然后我创建了一个简单的测试片段:

 @Test
    void GetRecordViaOrderDao() {
        try (CqlSession session = CqlSession.builder().build()) {

            DaoMapper daoMapper = new DaoMapperBuilder(session).build();
            OrderDao orderDao = daoMapper.orderDao(CqlIdentifier.fromCql("killrvideo"));
            CustomerOrders order = orderDao.findById("a");
            System.out.println(order.getCustomerEmail());
        }
    }

在这种情况下,我使用的是 "killrvideo" keyspace,因为我正在访问 Astra 数据库,那是我目前拥有的 keyspace。

结果:a@b.c.com

在我的 pom.xml 中指定了驱动程序版本 4.7.2。

英文:

Full Edit :

There are a few things going on here which confuses me, and the only way I could reproduce the error was to break the getter/setter which doesn't appear to be wrong on your code, but there is some copy/paste conversions that are happening. What I can so far see as follows:

  • The use of @Column(name = "id") - which is not an annotation from com.datastax.oss.driver.api.mapper.annotations. @CqlName should be used.
  • The use of a reserved keyword for a table - the term 'order' is a reserved keyword, I am pretty sure this results in considerable confusion within the code - although I got a different error when I attempted to use the keyword as a table name with the mapper. I think you should name this table to something else and avoid the keyword.

Annotation Link:
https://docs.datastax.com/en/developer/java-driver/4.2/manual/mapper/entities/ contains the rules / annotations available and you can see the use of @CqlName there to inform the mapper of the Cassandra column name if it differs from the naming convention.

I belive you were on the 4.2 driver in an earlier question - but if updated to 4.7 (recommended) then this is the link : https://docs.datastax.com/en/developer/java-driver/4.7/manual/mapper/entities/ )

The following code worked correctly:

Cql:

CREATE TABLE customer_orders (
    id text PRIMARY KEY,
    customer_email text,
    customer_id text,
    loyalty_id text
);

insert into customer_orders (id, customer_email, customer_id, loyalty_id) values ('a','a@b.c.com', '1234', '5678');

Pojo:

import com.datastax.oss.driver.api.mapper.annotations.CqlName;
import com.datastax.oss.driver.api.mapper.annotations.Entity;
import com.datastax.oss.driver.api.mapper.annotations.PartitionKey;

@Entity
public class CustomerOrders {
    @CqlName("id")
    @PartitionKey
    private String id;

    @CqlName("customer_id")
    private String customerId;

    @CqlName("loyalty_id")
    private String loyaltyId;

    @CqlName("customer_email")
    private String customerEmail;

    public CustomerOrders() {

    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getCustomerId() {
        return customerId;
    }

    public void setCustomerId(String customerId) {
        this.customerId = customerId;
    }

    public String getLoyaltyId() {
        return loyaltyId;
    }

    public void setLoyaltyId(String loyaltyId) {
        this.loyaltyId = loyaltyId;
    }

    public String getCustomerEmail() {
        return customerEmail;
    }

    public void setCustomerEmail(String customerEmail) {
        this.customerEmail = customerEmail;
    }
}

DaoMapper:

import com.datastax.oss.driver.api.core.CqlIdentifier;
import com.datastax.oss.driver.api.mapper.annotations.*;

@Mapper
public interface DaoMapper {

    @DaoFactory
    OrderDao orderDao(@DaoKeyspace CqlIdentifier keyspace);
}

OrderDao:

import com.datastax.oss.driver.api.mapper.annotations.Dao;
import com.datastax.oss.driver.api.mapper.annotations.Delete;
import com.datastax.oss.driver.api.mapper.annotations.Insert;
import com.datastax.oss.driver.api.mapper.annotations.Select;

@Dao
public interface OrderDao {

    @Select
    CustomerOrders findById(String id);

    @Insert
    void save(CustomerOrders order);

    @Delete
    void delete(CustomerOrders order);
}

I then created a simple test snippet:

 @Test
    void GetRecordViaOrderDao() {
        try (CqlSession session = CqlSession.builder().build()) {

            DaoMapper daoMapper = new DaoMapperBuilder(session).build();
            OrderDao orderDao = daoMapper.orderDao(CqlIdentifier.fromCql("killrvideo"));
            CustomerOrders order = orderDao.findById("a");
            System.out.println(order.getCustomerEmail());
        }
    }

killrvideo keyspace in this instance because I am hitting an Astra DB and thats the keyspace I have there currently.

Result: a@b.c.com

Driver version 4.7.2 was specified in my pom.xml

答案2

得分: 0

@Andrew 谢谢您的帮助,我之前在使用 @PartitionKey 时导入了错误的库。正确的导入方式是 import com.datastax.oss.driver.api.mapper.annotations.PartitionKey;,正如您提到的那样。

英文:

@Andrew thanks for that, I was using the wrong import for @PartitionKey. The correct one is this import com.datastax.oss.driver.api.mapper.annotations.PartitionKey; which you have mentioned.

huangapple
  • 本文由 发表于 2020年7月27日 22:12:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/63117195.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定