我已经使用 PartitionKey 注释声明了主键,但仍然得到 Entity Order does not declare a primary key
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;
}
... getters and setters
}
在以下代码中获取异常:
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';
完整编辑:
这里发生的一些事情让我感到困惑,我重现错误的唯一方法是打破 getter/setter,这在您的代码中似乎没有错,但是有一些 copy/paste 正在发生的转化。目前我能看到的如下:
- @Column(name = "id") 的使用 - 这不是来自 com.datastax.oss.driver.api.mapper.annotations 的注释。应该使用@CqlName。
- 为 table 使用保留关键字 - 术语 'order' 是保留关键字,我很确定这会导致代码中出现相当大的混乱 - 尽管我得到了一个不同的错误当我尝试将关键字用作映射器的 table 名称时。我认为您应该将此 table 命名为其他名称并避免使用关键字。
注释Link:
https://docs.datastax.com/en/developer/java-driver/4.2/manual/mapper/entities/ 包含可用的规则/注释,您可以在那里看到使用 @CqlName 来通知映射器 Cassandra 列名(如果它与命名约定不同)。
我相信你在之前的问题中使用的是 4.2 驱动程序 - 但如果更新到 4.7(推荐)那么这就是 link : 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');
波乔:
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 in this instance 因为我正在点击 Astra DB,这就是我目前拥有的键空间。
Result: a@b.c.com
我的 pom.xml
中指定了驱动程序版本 4.7.2
@Andrew 谢谢,我为 @PartitionKey
使用了错误的导入。正确的是你提到的这个import com.datastax.oss.driver.api.mapper.annotations.PartitionKey;
我有以下 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
}
在以下代码中获取异常:
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';
完整编辑:
这里发生的一些事情让我感到困惑,我重现错误的唯一方法是打破 getter/setter,这在您的代码中似乎没有错,但是有一些 copy/paste 正在发生的转化。目前我能看到的如下:
- @Column(name = "id") 的使用 - 这不是来自 com.datastax.oss.driver.api.mapper.annotations 的注释。应该使用@CqlName。
- 为 table 使用保留关键字 - 术语 'order' 是保留关键字,我很确定这会导致代码中出现相当大的混乱 - 尽管我得到了一个不同的错误当我尝试将关键字用作映射器的 table 名称时。我认为您应该将此 table 命名为其他名称并避免使用关键字。
注释Link: https://docs.datastax.com/en/developer/java-driver/4.2/manual/mapper/entities/ 包含可用的规则/注释,您可以在那里看到使用 @CqlName 来通知映射器 Cassandra 列名(如果它与命名约定不同)。
我相信你在之前的问题中使用的是 4.2 驱动程序 - 但如果更新到 4.7(推荐)那么这就是 link : 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');
波乔:
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 in this instance 因为我正在点击 Astra DB,这就是我目前拥有的键空间。
Result: a@b.c.com
我的 pom.xml
中指定了驱动程序版本 4.7.2@Andrew 谢谢,我为 @PartitionKey
使用了错误的导入。正确的是你提到的这个import com.datastax.oss.driver.api.mapper.annotations.PartitionKey;