How to Fix “No Converter Found Capable of Converting” for Custom Objects in Spring Data Cassandra

If you’ve tried to store a custom Java object inside a Cassandra table using Spring Data Cassandra and encountered an error like:

No converter found capable of converting from type [com.example.TransactionEntity] to type [com.datastax.oss.driver.api.core.data.UdtValue]

you’re not alone. This error appears when Spring Data Cassandra can’t map your Java class to a Cassandra User-Defined Type (UDT). In this article, you’ll learn why this happens and how to fix it step-by-step.


Why the Error Happens

Cassandra stores primitive types (text, int, boolean, etc.) easily, but when you embed a complex object in another entity (for example, a TransactionEntity inside an Account entity), Spring Data Cassandra expects a corresponding UDT to be defined in the keyspace. Without a UDT or a converter, Spring cannot serialize the object to Cassandra’s format, which triggers the “No converter found…” exception.


Step 1: Define a User-Defined Type in Cassandra

First, create a UDT in your Cassandra keyspace that matches your Java object fields:

CREATE TYPE IF NOT EXISTS transaction_type (
    mandate_id text,
    check_id text,
    creditor_id text
);

This schema corresponds to a Java class like:

public class TransactionEntity {
    private String mandateId;
    private String checkId;
    private String creditorId;
    // getters and setters
}

Step 2: Annotate Your Java Classes

Mark your UDT class with @UserDefinedType so Spring knows it maps to a Cassandra type:

import org.springframework.data.cassandra.core.mapping.UserDefinedType;

@UserDefinedType("transaction_type")
public class TransactionEntity {
    private String mandateId;
    private String checkId;
    private String creditorId;
    // getters and setters
}

Then, in your entity class, refer to the UDT:

@Table("accounts")
public class Account {
    @PrimaryKey
    private String id;

    private TransactionEntity transaction; // mapped to transaction_type
}

Step 3: Register a UserDefinedType Bean

If you prefer to manually control the mapping (or need access to UdtValue), expose the UDT as a Spring bean:

@Configuration
public class CassandraConfig {

    private final CqlSession session;

    public CassandraConfig(CqlSession session) {
        this.session = session;
    }

    @Bean
    public UserDefinedType transactionType() {
        return session.getMetadata()
            .getKeyspace("your_keyspace").orElseThrow()
            .getUserDefinedType("transaction_type").orElseThrow();
    }
}

This ensures Spring can inject the UserDefinedType into your converters or services.


Step 4: (Optional) Write a Custom Converter

For fine-grained control, write a converter to transform your Java object into a UdtValue:

public class TransactionEntityToUdtConverter
        implements Converter<TransactionEntity, UdtValue> {

    private final UserDefinedType udtType;

    public TransactionEntityToUdtConverter(UserDefinedType udtType) {
        this.udtType = udtType;
    }

    @Override
    public UdtValue convert(TransactionEntity source) {
        if (source == null) return null;
        return udtType.newValue()
                .setString("mandate_id", source.getMandateId())
                .setString("check_id", source.getCheckId())
                .setString("creditor_id", source.getCreditorId());
    }
}

Register the converter:

@Bean
public CassandraCustomConversions cassandraCustomConversions(UserDefinedType transactionType) {
    return new CassandraCustomConversions(
        List.of(new TransactionEntityToUdtConverter(transactionType))
    );
}

Step 5: Save and Query the Data

Now you can persist your objects without errors:

accountRepository.save(new Account("123",
    new TransactionEntity("m1", "c1", "cr1")));

Spring Data Cassandra will convert your TransactionEntity into the UDT automatically.


SEO Keywords to Target

  • Spring Data Cassandra custom object mapping
  • Cassandra User Defined Type Java example
  • No converter found capable of converting UdtValue
  • Spring Cassandra @UserDefinedType
  • CassandraCustomConversions example

Final Thoughts

The “No converter found…” error is a common stumbling block when moving from simple Cassandra schemas to richer domain models. The fix is to:

  1. Define a UDT in Cassandra.
  2. Map your Java class with @UserDefinedType.
  3. Optionally create a custom converter.
  4. Register a UserDefinedType bean if needed.

Following these steps ensures Spring Data Cassandra can seamlessly convert your Java objects to Cassandra’s storage format.

This article is inspired by real-world challenges we tackle in our projects. If you're looking for expert solutions or need a team to bring your idea to life,

Let's talk!

    Please fill your details, and we will contact you back

      Please fill your details, and we will contact you back