spring-projects / spring-projects/spring-ai
Cassandra chat memory schema initialisation fails on native protocol V4
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 9.5k
- Forks
- 2.9k
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 6
Description
Bug description
CassandraChatMemoryRepositoryConfig.ensureMessageTypeExist() executes its CREATE TYPE with a per-request keyspace:
SimpleStatement stmt = SchemaBuilder.createType(this.messageUDT)
.ifNotExists()
.withField(this.messageUdtTimestampColumn, DataTypes.TIMESTAMP)
.withField(this.messageUdtTypeColumn, DataTypes.TEXT)
.withField(this.messageUdtContentColumn, DataTypes.TEXT)
.build();
this.session.execute(stmt.setKeyspace(this.schema.keyspace));
The driver permits a per-request keyspace only on native protocol V5 and above (DefaultProtocolVersionRegistry.supports, DefaultProtocolFeature.PER_REQUEST_KEYSPACE), so on a V4 connection the statement throws client-side before it reaches the server:
Failed to instantiate [org.springframework.ai.chat.memory.repository.cassandra.CassandraChatMemoryRepository]:
Factory method 'cassandraChatMemoryRepository' threw exception with message:
Can't use per-request keyspace with protocol V4
This makes the module's default configuration, spring.ai.chat.memory.repository.cassandra.initialize-schema=true, unusable against any server that negotiates V4.
Two secondary points:
ensureMessageTypeExist()has no metadata guard, unlikeensureTableExists()andSchemaUtil.ensureKeyspaceExists(). It runs on every startup, so pre-creating the type does not avoid the failure. Settinginitialize-schema=falseand creating the schema by hand is the only workaround.SchemaBuilderalready has a keyspace-taking overload,createType(String keyspace, String typeName), so the per-request keyspace is not needed.
Environment
Spring AI 1.1.8 and every release back to 1.0.0; the statement is byte-identical in 1.0.0, 1.0.3, 1.1.0, 1.1.2 and 1.1.8. Reproduced with java-driver-core 4.18.1 as managed by Spring Boot 3.4.13.
Steps to reproduce
Against any Cassandra 5.0 node with the session pinned to V4, standing in for Astra's ceiling:
DriverConfigLoader v4 = DriverConfigLoader.programmaticBuilder()
.withString(DefaultDriverOption.PROTOCOL_VERSION, "V4")
.build();
CqlSession session = CqlSession.builder()
.addContactPoint(contactPoint)
.withLocalDatacenter("datacenter1")
.withConfigLoader(v4)
.build();
CassandraChatMemoryRepository.create(CassandraChatMemoryRepositoryConfig.builder()
.withCqlSession(session)
.withKeyspaceName("test_ks")
.build());
Expected behavior
Schema initialisation succeeds on V4. Qualifying the type in the statement rather than per request is protocol-agnostic:
SimpleStatement stmt = SchemaBuilder.createType(this.schema.keyspace, this.messageUDT)
...
this.session.execute(stmt);
With that change the same reproduction above creates the type, the table, and round-trips messages on V4. I have verified this locally and will open a pull request.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in CassandraChatMemoryRepositoryConfig.ensureMessageTypeExist(), then compare its schema initialization with ensureTableExists() and SchemaUtil.ensureKeyspaceExists(). Run the issue's session-pinned V4 reproduction; done means initialization creates the type and table and messages round-trip successfully without the per-request keyspace error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cassandra, java
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 88/100