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';
Advertisement
Answer
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