Hi I'm trying to set up the Java Mapper system(version 4.13.0) to work properly with Immutable Entity classes(annotated with @PropertyStrategy(mutable = false, getterStyle = JAVABEANS)) where I've modified the entities so that nullable values(which can be base types like text and numbers as well as @Entity mapped UDTs ) are only accessible via getters that return an java.util.Optional<?>.
I'm able to write the Entity class, and the java-driver-mapper-processor will generate it's helper code(I'm not sure it's right, but I'm not getting errors at build time).
But at runtime it doesn't seem to be happy with me. It's complaining about not finding a valid codex:
Codec not found for requested operation: [UDT(testSchema."com.example.EntityClass") <-> java.util.Optional<com.example.EntityClass>] com.datastax.oss.driver.api.core.type.codec.CodecNotFoundException: Codec not found for requested operation: [UDT(testSchema."com.example.EntityClass") <-> java.util.Optional<com.example.EntityClass>] at app//com.datastax.oss.driver.internal.core.type.codec.registry.CachingCodecRegistry.createCodec(CachingCodecRegistry.java:609)
I understand at a basic level what a codex does, and I've registered some previously to do mundane things like timestamp<=>Instant, and deal with with java Enums. I've also seen the pages in the docs that show the Optional codex(ExtraTypeCodecs.optionalOf(TypeCodecs.UUID);).
But I'm having trouble finding something that can help me with how to set it up to work with a UDT. Is there some example in the docs that I've missed? Secondly, is there something I can do to have this codex for Optional<>, once registered, just work for all Entity annotated UDTs and even the native types?
thank you for your time.
FYI, here's a minimal code example, FYI, before I added the optionalB field, it was working correctly. If you want more information or in a different format let me know.
cql:
create type testSchema.EntityB( mandatory text, optional text ); create table testSchema.EntityA( mandatory text, optional text, mandatory_b frozen<EntityB>, optional_b frozen<EntityB>, PRIMARY KEY ( mandatory ) )
session configuration:
CqlSessionBuilder builder = CqlSession.builder() .withConfigLoader(loader) .addTypeCodecs(ExtraTypeCodecs.TIMESTAMP_UTC, ExtraTypeCodecs.enumNamesOf(OperationStatus.class), ExtraTypeCodecs.optionalOf(TypeCodecs.TEXT));
entity classes:
@Entity @CqlName("EntityA") @PropertyStrategy(mutable = false, getterStyle = JAVABEANS) public class EntityA { @PartitionKey private final String mandatory; private final String optional; private final EntityB mandatoryB; private final EntityB optionalB; public EntityA(String mandatory, String optional, EntityB mandatoryB,EntityB optionalB ){ assert mandatory != null; this.mandatory = mandatory; this.optional = optional; this.mandatoryB = mandatoryB; this.optionalB = optionalB; } public EntityA( String mandatory, Optional<String> optional, EntityB mandatoryB, Optional<EntityB> optionalB ){ assert mandatory != null; assert mandatoryB != null; this.mandatory = mandatory; this.optional = optional.orElse(null); this.mandatoryB = mandatoryB; this.optionalB = optionalB.orElse(null); } public String getMandatory(){ return mandatory; } public Optional<String> getOptional(){ return Optional.ofNullable(optional); } public EntityB getMandatoryB(){ return mandatoryB; } public Optional<EntityB> getOptionalB(){ return Optional.ofNullable(mandatoryB); } }
and
@Entity @CqlName("EntityB") @PropertyStrategy(mutable = false, getterStyle = JAVABEANS) public class EntityB { private final String mandatory; private final String optional; public EntityB(String mandatory, String optional){ assert mandatory != null; this.mandatory = mandatory; this.optional = optional; } public EntityB(String mandatory, Optional<String> optional){ assert mandatory != null; this.mandatory = mandatory; this.optional = optional.orElse(null); } public String getMandatory(){ return mandatory; } public Optional<String> getOptional(){ return Optional.ofNullable(optional); } }
here's the error:
Caused by: java.lang.IllegalArgumentException: The CQL ks.table: exampleSchema.entitya defined in the entity class: com.example.EntityA declares type mappings that are not supported by the codec registry: Field: optional_b, Entity Type: java.util.Optional<com.example.EntityB>, CQL type: UDT(exampleSchema.entityb) at com.datastax.oss.driver.internal.mapper.entity.EntityHelperBase.throwMissingTypesIfNotEmpty(EntityHelperBase.java:221) at com.datastax.oss.driver.internal.mapper.entity.EntityHelperBase.throwMissingTableTypesIfNotEmpty(EntityHelperBase.java:210) at com.example.EntityAHelper__MapperGenerated.validateEntityFields(EntityAHelper__MapperGenerated.java:256) at com.example.ReadDaoImpl__MapperGenerated.initAsync(ReadDaoImpl__MapperGenerated.java:267)