spring-projects / spring-data-cassandra

Provides support to increase developer productivity in Java when using Apache Cassandra. Uses familiar Spring concepts such as a template classes for core API usage and lightweight repository style data access.
https://spring.io/projects/spring-data-cassandra/
Apache License 2.0
374 stars 307 forks source link

Implementing keyspace qualification for particular entities #1400

Open mipo256 opened 1 year ago

mipo256 commented 1 year ago

Hello @mp911de @schauder ! I have implemented #921 feature. I have assumed the following behavoir:

  1. There is a possibility to specify a keyspace for an entity in the @Table annotation. If it is specified, then for each query we just pass to QueryBuilder keyspace specified by user. The goal again is not to mutate CqlSession and avoid creating CqlSession for each keyspace.
  2. On the other hand, if keyspace is omitted or empty, we assume the entity's corresponding table is in the default for current CqlSession namespace.

I hope it makes sence to you as well. Any suggestions/improvements will be highly appretiated. Thanks!

mp911de commented 1 year ago

Have you seen #179? Introducing keyspace to tables raises another set of questions that we tried to address with the previous pull request. For simplicity, let's decouple all polishing within this pull request into a separate one, as the cleanups are almost a no-brainer to merge.

mipo256 commented 1 year ago

@mp911de No, not yet. But I have checked it now.

  1. https://github.com/spring-projects/spring-data-cassandra/pull/179#pullrequestreview-466699019

Regardign this commet, I think it is the good idea. So we'll just introduce new getTableInfo() method that would return a complex object with keyspace and table name. I guess then we need to mark getTableName() as @Deprecated since accessign table name without keyspace actually loses the sense.

P.S: Also I think we should not expose setTableName() to be honest. Ideally, it should be immutable and passed to Cassandra PersistentEntity by the time of it's creation.

2.https://github.com/spring-projects/spring-data-cassandra/pull/179#issuecomment-684514908

I can introduce new overloaded methods to an API of CassandraTemplate to accept this new TableCoordinates, no problem.

Any other key components for me to consider?)

By the way, I have separated the polishing commits already. You want me to create a separate PR for this?)

mp911de commented 1 year ago

Applying a keyspace to a table sounds straight-forward, but there are a few things to consider:

  1. CassandraTemplate and the underlying CqlTemplate operate within a single keyspace as CqlSession is bound to a keyspace. This complicates schema support as we create a table/user type within that keyspace. All of our specifications (e.g. AlterTableSpecification, CreateTableSpecification) would require another keyspace property to define a different keyspace to generate the appropriate DML statements.
  2. Tables using user-defined types from different keyspaces would require an appropriate resolution mechanism. UserTypeResolver accepts a name only as it is tied to a single keyspace.

IMO, the keyspace isn't something that is detached from the actual identifier but it rather enriches it. A much more appropriate way to think about this is thinking whether the identifier is qualified or unqualified and having an extension to CqlIdentifier in the sense of QualifiedCqlIdentifier. Such an approach could allow not to introduce of additional API but rather consider qualified identifiers in e.g. SimpleUserTypeResolver, the CQL generator, or our StatementFactory. For this to be possible, CqlIdentifier's constructor must be protected to allow subclasses.

mp911de commented 1 year ago

I filed https://datastax-oss.atlassian.net/browse/JAVA-3088 asking for constructor rules relaxation.

mipo256 commented 1 year ago

Yeah, I agree with you. I also think we should think of keyspace and table name as a single identifier of the table in cassandra cluster. For this I have created the PR in datastax java driver: https://github.com/datastax/java-driver/pull/1683