【问题标题】:Cassandra Spring Data doesn't let me query data by composite primary key directlyCassandra Spring Data不允许我直接通过复合主键查询数据
【发布时间】:2018-10-06 02:33:33
【问题描述】:

我正在尝试使用复合主键类来使用 Spring Data Cassandra。但是当我尝试查询数据时出现异常:

org.springframework.data.repository.query.QueryCreationException: **Could not create query for public abstract java.util.List com.amdocs.cassandrapoc.repository.ServiceRepository.findByKey(com.amdocs.cassandrapoc.entities.Key)! Reason: Cannot use composite primary key directly. Reference a property of the composite primary key**

这是我的代码:

@PrimaryKeyClass
public class Key implements Serializable {

   @PrimaryKeyColumn(name = "id", ordinal = 0, type = 
      PrimaryKeyType.PARTITIONED)
   @CassandraType(type = DataType.Name.UUID)
      private UUID id;
   @PrimaryKeyColumn(name = "tenant", ordinal = 1, type = 
      PrimaryKeyType.PARTITIONED)
   @CassandraType(type = DataType.Name.TEXT)
      private String tenant;
  (Equals, hashcode, getters, setters omitted)
}

Table(value = "service")
public class Service implements Serializable {
   @PrimaryKey
   private Key key;

   @Column
   private String value;
   (constructors, setters, getters omitted)
}

@Repository
public interface ServiceRepository extends CassandraRepository<Service, Key> {

    List<Service> findByKey(Key key);

}

这就是我创建表的方式(使用嵌入式 Cassandra 和 junit):

@Autowired
private CassandraAdminOperations adminTemplate;
private final String DATA_TABLE_NAME = "service";

@Before
public void createTable() {
    adminTemplate.createTable(
            true, CqlIdentifier.of(DATA_TABLE_NAME),
            Service.class, new HashMap<String, Object>());
}

我做错了什么?

【问题讨论】:

  • 可以添加表定义吗?
  • 我使用嵌入式 Cassandra,并且每次在 Junit 中使用服务类结构创建表:private CassandraAdminOperations adminTemplate;私有最终字符串 DATA_TABLE_NAME = "服务";私人最终字符串租户=“测试”; @Before public void createTable() { adminTemplate.createTable( true, CqlIdentifier.of(DATA_TABLE_NAME), Service.class, new HashMap()); }
  • 我编辑了我的原始邮件以获得更好的格式
  • 我还检查了未嵌入的 Cassandra CREATE TABLE 服务(id uuid,租户文本,值 blob,主键((id,租户)));同样的结果
  • 我尝试使用 CrudRepository 接口 findById(Key key) 的标准方法,它现在可以工作了。

标签: java cassandra spring-data composite-key spring-data-cassandra


【解决方案1】:

尝试使用 CrudRepository 代替 CassandraRepository:

基于 CassandraRepository 的存储库可以定义单个主键、使用主键类或不带主键类的复合主键。使用复合主键而没有主键类的类型必须使用 MapId 来声明其键值。

来源:https://docs.spring.io/spring-data/cassandra/docs/current/api/org/springframework/data/cassandra/repository/CassandraRepository.html

【讨论】:

  • 如果您添加一个带有MapId 的示例会有所帮助。
【解决方案2】:

我遇到了同样的问题。这是通过使用 Cassandra spring framework 提供的 AbstractCassandraConfiguration 定义 Cassandra Configuration 来解决的。

@Configuration
@EnableCassandraRepositories(basePackages = "A.B.Z")  // package location of repository
@ComponentScan(value = "X.Y.X")  // enable autowire
public class CassandraConfiguration extends AbstractCassandraConfiguration {

    public String getContactPoints() {
        return "HOTNAME OF CASSANDRA CLUSTER"; // your cluster host 
    }

    @Override
    protected int getPort() {
        return 9042; //default port
    }

    @Override
    protected String getKeyspaceName() {
        return "YOUR KEY SPACE NAME";  // Cassandra Keyspace Name
    }

}

【讨论】:

    【解决方案3】:

    我遇到了同样的问题。我通过以下实现解决了我的问题。

    @Repository
    public interface ServiceRepository extends CassandraRepository<Service, Key> {
    
        List<Service> findByKeyIdAndKeyTenant(UUID id, String tenant);
    
    }
    

    【讨论】:

      【解决方案4】:

      我遇到了同样的问题,但使用以下实现方式解决。

      @Repository
      public interface ServiceRepository extends CassandraRepository<Service, Key> {
      
          List<Service> findByKeyTent(Key key);
          // findBy{PrimaryKey}{PrimaryKeyColumn} format
      }
      

      【讨论】:

        猜你喜欢
        • 2021-12-27
        • 2016-03-25
        • 2017-11-12
        • 2018-08-31
        • 2020-10-12
        • 2021-09-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多