英文:
Codec not found for requested operation: [UDT("keyspace".user_product_info) <->model.user.UserProductInfo]
问题
问题:
我正在使用DataStax Java Driver 4.9,我在我的 keyspace 中声明了一个 UDT(user_product_info),它使用了嵌套的 UDTs... 在运行程序时,当执行以下代码时显示“找不到编解码器”错误:
PreparedStatement preparedUpdateFriendRating = session.prepare("UPDATE friend_rating SET user_product_infos=:userproductinfos WHERE user_id=:userId ;");
preparedUpdateFriendRating.bind(new ArrayList(userProductInfo), id);
以下是 shema.cql:
CREATE TYPE IF NOT exists user_product_info (id text,short_product frozen < short_product>,test set < text >,ratings list< frozen < rating > >);
CREATE TABLE IF NOT exists friend_rating(user_id text,user_product_infos list < frozen < user_product_info >>,PRIMARY KEY (user_id));
CREATE TYPE IF NOT exists short_product (name text,specs SET < text >,img text);
对应的 Java 类:
//------------------------------------USER PRODUCT INFO-----------
@SchemaHint(targetElement = UDT)
public class UserProductInfo {
@CqlName("id")
private String productId;
@CqlName("short_product")
private ShortProduct shortProduct;
@CqlName("test")
private Set<String> test;
@CqlName("ratings")
private List<Rating> ratings;
public UserProductInfo() {}
// 包含 getter 和 setter 方法
}
//---------------------------------------SHORT PRODUCT----------------
@SchemaHint(targetElement = UDT)
public class ShortProduct {
@CqlName("name")
private String name;
@CqlName("specs")
private Set<String> specs;
@CqlName("img")
private String imageUrl;
public ShortProduct() {}
// 包含 getter 和 setter 方法
}
//--------------------------------------FRIEND RATING TABLE-------------------
@SchemaHint(targetElement = TABLE)
public class FriendRating {
@PartitionKey
@CqlName("user_id")
private String userId;
@CqlName("user_product_infos")
private List<UserProductInfo> userProductInfos;
// 包含 getter 和 setter 方法
}
附带的堆栈跟踪:
com.datastax.oss.driver.api.core.type.codec.CodecNotFoundException: 请求的操作找不到编解码器:[UDT("keyspace".user_product_info) <-> model.user.UserProductInfo]
at com.datastax.oss.driver.internal.core.type.codec.registry.CachingCodecRegistry.createCodec(CachingCodecRegistry.java:609) ~[java-driver-core-4.6.1.jar:na]
...
at com.datastax.oss.driver.internal.core.data.ValuesHelper.encodePreparedValues(ValuesHelper.java:112) ~[java-driver-core-4.6.1.jar:na]
at com.datastax.oss.driver.internal.core.cql.DefaultPreparedStatement.bind(DefaultPreparedStatement.java:159) ~[java-driver-core-4.6.1.jar:na]
英文:
Issue :
I am using DataStax Java Driver 4.9 I have declared a UDT user_product_info in my keyspace and this uses nested UDTs......while running the program it shows Codec not found when executing the following line
**
PreparedStatement preparedUpdateFriendRating = session.prepare("UPDATE friend_rating SET user_product_infos=:userproductinfos WHERE user_id=:userId ;");
preparedUpdateFriendRating.bind(new ArrayList(userProductInfo), id);
**
following is the shema.cql
CREATE TYPE IF NOT exists user_product_info (id text,short_product frozen < short_product>,test set < text >,ratings list< frozen < rating > >);
CREATE TABLE IF NOT exists friend_rating(user_id text,user_product_infos list < frozen < user_product_info >>,PRIMARY KEY (user_id));
CREATE TYPE IF NOT exists short_product (name text,specs SET < text >,img text);
With corresponding java class
//------------------------------------USER PRODUCT INFO-----------
@SchemaHint(targetElement = UDT)
public class UserProductInfo {
@CqlName("id")
private String productId;
@CqlName("short_product")
private ShortProduct shortProduct;
@CqlName("test")
private Set<String> test;
@CqlName("ratings")
private List<Rating> ratings;
public UserProductInfo() {}
//with getters and setters
}
//---------------------------------------SHORT PRODUCT----------------
@SchemaHint(targetElement = UDT)
public class ShortProduct {
@CqlName("name")
private String name;
@CqlName("specs")
private Set<String> specs;
@CqlName("img")
private String imageUrl;
public ShortProduct() {}
//with getters and setters
}
//--------------------------------------FRIEND RATING TABLE-------------------
@SchemaHint(targetElement = TABLE)
public class FriendRating {
@PartitionKey
@CqlName("user_id")
private String userId;
@CqlName("user_product_infos")
private List<UserProductInfo> userProductInfos;
//with getters and setters
}
'''
with following stack trace:
com.datastax.oss.driver.api.core.type.codec.CodecNotFoundException: Codec not found for requested operation: [UDT("keyspace".user_product_info) <-> model.user.UserProductInfo]
at com.datastax.oss.driver.internal.core.type.codec.registry.CachingCodecRegistry.createCodec(CachingCodecRegistry.java:609) ~[java-driver-core-4.6.1.jar:na]
at com.datastax.oss.driver.internal.core.type.codec.registry.DefaultCodecRegistry$1.load(DefaultCodecRegistry.java:95) ~[java-driver-core-4.6.1.jar:na]
at com.datastax.oss.driver.internal.core.type.codec.registry.DefaultCodecRegistry$1.load(DefaultCodecRegistry.java:92) ~[java-driver-core-4.6.1.jar:na]
at com.datastax.oss.driver.shaded.guava.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3527) ~[java-driver-shaded-guava-25.1-jre.jar:na]
at com.datastax.oss.driver.shaded.guava.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2276) ~[java-driver-shaded-guava-25.1-jre.jar:na]
at com.datastax.oss.driver.shaded.guava.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2154) ~[java-driver-shaded-guava-25.1-jre.jar:na]
at com.datastax.oss.driver.shaded.guava.common.cache.LocalCache$Segment.get(LocalCache.java:2044) ~[java-driver-shaded-guava-25.1-jre.jar:na]
at com.datastax.oss.driver.shaded.guava.common.cache.LocalCache.get(LocalCache.java:3951) ~[java-driver-shaded-guava-25.1-jre.jar:na]
at com.datastax.oss.driver.shaded.guava.common.cache.LocalCache.getOrLoad(LocalCache.java:3973) ~[java-driver-shaded-guava-25.1-jre.jar:na]
at com.datastax.oss.driver.shaded.guava.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4957) ~[java-driver-shaded-guava-25.1-jre.jar:na]
at com.datastax.oss.driver.shaded.guava.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:4963) ~[java-driver-shaded-guava-25.1-jre.jar:na]
at com.datastax.oss.driver.internal.core.type.codec.registry.DefaultCodecRegistry.getCachedCodec(DefaultCodecRegistry.java:117) ~[java-driver-core-4.6.1.jar:na]
at com.datastax.oss.driver.internal.core.type.codec.registry.CachingCodecRegistry.codecFor(CachingCodecRegistry.java:196) ~[java-driver-core-4.6.1.jar:na]
at com.datastax.oss.driver.internal.core.type.codec.registry.CachingCodecRegistry.createCodec(CachingCodecRegistry.java:567) ~[java-driver-core-4.6.1.jar:na]
at com.datastax.oss.driver.internal.core.type.codec.registry.DefaultCodecRegistry$1.load(DefaultCodecRegistry.java:95) ~[java-driver-core-4.6.1.jar:na]
at com.datastax.oss.driver.internal.core.type.codec.registry.DefaultCodecRegistry$1.load(DefaultCodecRegistry.java:92) ~[java-driver-core-4.6.1.jar:na]
at com.datastax.oss.driver.shaded.guava.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3527) ~[java-driver-shaded-guava-25.1-jre.jar:na]
at com.datastax.oss.driver.shaded.guava.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2276) ~[java-driver-shaded-guava-25.1-jre.jar:na]
at com.datastax.oss.driver.shaded.guava.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2154) ~[java-driver-shaded-guava-25.1-jre.jar:na]
at com.datastax.oss.driver.shaded.guava.common.cache.LocalCache$Segment.get(LocalCache.java:2044) ~[java-driver-shaded-guava-25.1-jre.jar:na]
at com.datastax.oss.driver.shaded.guava.common.cache.LocalCache.get(LocalCache.java:3951) ~[java-driver-shaded-guava-25.1-jre.jar:na]
at com.datastax.oss.driver.shaded.guava.common.cache.LocalCache.getOrLoad(LocalCache.java:3973) ~[java-driver-shaded-guava-25.1-jre.jar:na]
at com.datastax.oss.driver.shaded.guava.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4957) ~[java-driver-shaded-guava-25.1-jre.jar:na]
at com.datastax.oss.driver.shaded.guava.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:4963) ~[java-driver-shaded-guava-25.1-jre.jar:na]
at com.datastax.oss.driver.internal.core.type.codec.registry.DefaultCodecRegistry.getCachedCodec(DefaultCodecRegistry.java:117) ~[java-driver-core-4.6.1.jar:na]
at com.datastax.oss.driver.internal.core.type.codec.registry.CachingCodecRegistry.codecFor(CachingCodecRegistry.java:258) ~[java-driver-core-4.6.1.jar:na]
at com.datastax.oss.driver.internal.core.data.ValuesHelper.encodePreparedValues(ValuesHelper.java:112) ~[java-driver-core-4.6.1.jar:na]
at com.datastax.oss.driver.internal.core.cql.DefaultPreparedStatement.bind(DefaultPreparedStatement.java:159) ~[java-driver-core-4.6.1.jar:na]
答案1
得分: 1
你有两个选择来解决这个问题:
-
按照文档中的描述,为你的UDT实现自定义代码(我不想从中复制代码)。这是必需的,因为你正在使用核心API(
session.execute
)。 -
切换使用对象映射器 - 你将直接使用你的对象,加载和保存它们等等。你已经开始使用
@CqlName
对你的对象进行注释,但是它们并没有被使用,因为你需要设置预处理器来根据这些注释生成代码。(对于简单的字段名称,比如names
等,你也不需要进行注释。对于更复杂的名称,你可能也不需要,因为对象映射器具有不同的命名转换器,比如驼峰式命名到下划线命名等)。
英文:
You have 2 alternatives to solve this problem:
-
Implement custom code for your UDT as described in documentation (I don't want to copy code from it). It's required because you're using core API (
session.execute
) -
Switch to use object mapper - you'll work with your objects directly, loading and saving them, etc.. You already started to annotate your objects with
@CqlName
, but they aren't used because you need to setup preprocessor for generation of the code based on this annotations. (you also don't need to have annotations for simple field names, like,names
, etc. You also may not need this for more complex names, because object mapper has different naming translators, like, camel case to snake case, etc.)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论