简体   繁体   English

找不到我的课程的编解码器(CodecConfigurationException)

[英]Can't find a codec for my class (CodecConfigurationException)

I need to save a java object in mongodb database. 我需要在mongodb数据库中保存一个Java对象。 This object has an other object into it. 该对象包含另一个对象。 When I try to save, I receive the error message on console: 当我尝试保存时,在控制台上收到错误消息:

org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class Item.

The problem is that I created the codec for class Item, but, it can't work even registering it. 问题是我为类Item创建了编解码器,但是,即使注册它也无法正常工作。 See the classes for best understanding. 请参阅课程以获得最佳理解。

Models 楷模

public class Card(){

  public Card(){
   itens = new ArrayList<Item>()
  }
  String id;
  String description;
  List<Item> itens;
  .
  .
  .

}
public class Item(){

  String id;
  String name; 
  .
  .
  .

}

CardCodec 卡编解码器

public class CardCodec implements CollectibleCodec<Card>{
  private final Codec<Document> documentCodec;

  public CardCodec() {      
    this.documentCodec = new DocumentCodec();
  }

  @Override
  public void encode(BsonWriter writer, Card card, EncoderContext encoderContext) {
  Document cardDoc = new Document();
    String id = card.getId();
    String description = card.getDescription();  
    List<Item> itens = card.getItens();

    if(id != null) {
        cardDoc.put("_id", new ObjectId(id));
    }
    if(description != null){
        cardDoc.put("description", card.getDescription);
    }
    if(Itens != null){
        cardDoc.put("itens", card.getItens());
    }
    this.documentCodec.encode(writer, cardDoc, encoderContext);
  }

    @Override
    public Class<Card> getEncoderClass() {      
        return Card.class;
    }

    @Override
    public Card decode(BsonReader reader, DecoderContext decoderContext) {
        Document cardDoc = this.documentCodec.decode(reader, decoderContext);
        Card card=  new Card();

        card.setId(cardDoc .getObjectId("_id").toHexString());
        card.setDescription(cardDoc .getString("description"));

        List<Document> itensDoc =  cardDoc.getList("itens", Document.class);
        List<Item> itens = new ItemConverter().convertToListItem(itensDoc);
        card.setItens(itens);
        return card;
    }

    @Override
    public Card generateIdIfAbsentFromDocument(Card card) {

        if( !documentHasId(card) ) {
        card.setId(new ObjectId().toHexString());
        }

        return card;

    }

    @Override
    public boolean documentHasId(Card card) {       
        return null != card.getId();
    }

    @Override
    public BsonValue getDocumentId(Card card) {
        if(!documentHasId(card)) {
            throw new IllegalStateException("Esse documento não tem um _id");
        }
        return new BsonString(card.getId());
    }

}

Converter 转换器

public class ItemConverter {

    public Item convert(Document doc) {
        Item item = new Item();
        String id = doc.getObjectId("_id").toHexString();
        String description = doc.getString("description");
        item.setId(id);
        item.setName(description);
        return item;
    }

    public List<Item> convertToListItem(List<Document> ItensDocs){      
        List<Item> itens = new ArrayList<Item>();   
        if(ItensDocs== null) {
           return Collections.emptyList();
        }
        for(Document doc: ItensDocs) {           
           itens.add( this.convert(doc) );
        }
        return itens;
    }

}

ItemCodec ItemCodec

public class ItemCodec implements CollectibleCodec<Item>{
    private final Codec<Document> documentCodec;

    public ItemCodec() {    
        this.documentCodec = new DocumentCodec();
    }

    @Override
    public void encode(BsonWriter writer, Item value, EncoderContext encoderContext) {
        Document itemDoc = new Document();

        String id = value.getId();
        String name = value.getName();

        if(id != null) {
            itemDoc.put("_id", new ObjectId(id));
        }
        if(name != null) {
            itemDoc.put("name", value.getName());
        }

        documentCodec.encode(writer, itemDoc, encoderContext);
    }

    @Override
    public Class<Item> getEncoderClass() {      
        return Item.class;
    }

    @Override
    public Item decode(BsonReader reader, DecoderContext decoderContext) {      
        Document document = documentCodec.decode(reader, decoderContext);       
        return new ItemConverter().convert(document);
    }

    @Override
    public Item generateIdIfAbsentFromDocument(Item item) {
        if(!this.documentHasId(item)) {
            item.setId(new ObjectId().toHexString());           
        }
        return item;        
    }

    @Override
    public boolean documentHasId(Item item) {       
        return null != item.getId();
    }

    @Override
    public BsonValue getDocumentId(Item item) {
        if(!documentHasId(item)) {
            throw new IllegalStateException("Esse documento não tem um _id");
        }

        return new BsonString(item.getId());

    }


}

Now, how I registry the codecs 现在,我如何注册编解码器

...
    CardCodec cardCodec = new CardCodec();
    ItemCodec itemCodec = new ItemCodec();

    this.codecRegistry = CodecRegistries.fromRegistries(
                MongoClientSettings.getDefaultCodecRegistry(),
                CodecRegistries.fromCodecs(cardCodec, itemCodec)
    );

this.cardCollection = this.mongoDatabase.getCollection("cards", Card.class).withCodecRegistry(this.codecRegistry);
...

When I try to execute an insert: 当我尝试执行插入时:

this.cardCollection.insertOne(card);

I receive: 我收到:

org.bson.codecs.configuration.CodecConfigurationException

It's tricky to write correct and efficient POJO Codec implementations by hand. 手工编写正确且有效的POJO编解码器实现很棘手。 In this case the problem is that the DocumentCodec that you instantiate within the CardCodec is not configured with a CodecRegistry that contains the ItemCodec, so it is unable to find the ItemCodec. 在这种情况下,问题在于您在CardCodec中实例化的DocumentCodec没有配置包含ItemCodec的CodecRegistry,因此无法找到ItemCodec。

There are ways that you can fix your Codec implementations, but I'm not clear why you want to roll your own when the driver has a general solution for this. 您可以通过多种方法来修复Codec的实现,但是我不清楚为什么当驱动程序有一个通用的解决方案时,为什么要自己动手。 See POJO Support for details. 有关详细信息,请参见POJO支持

Simply create your CodecRegistry like this: 只需像这样创建您的CodecRegistry:

        CodecRegistry codecRegistry = CodecRegistries.fromRegistries(
            MongoClientSettings.getDefaultCodecRegistry(),
            CodecRegistries.fromProviders(PojoCodecProvider.builder().automatic(true).build())
    );

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Morphia - CodecConfigurationException:找不到类的编解码器 - 但类已注册 - Morphia - CodecConfigurationException: Can't find a codec for class - But class is registered spring-boot 2.1.0 mongo-CodecConfigurationException:找不到类java.time.Year的编解码器 - spring-boot 2.1.0 mongo - CodecConfigurationException: Can't find a codec for class java.time.Year mongo-operations spring mongo批量操作执行异常(CodecConfigurationException:找不到类的编解码器) - mongo-operations spring mongo bulk opeartion execution exception (CodecConfigurationException: Can't find a codec for class) org.bson.codecs.configuration.CodecConfigurationException:找不到类 org.hibernate.ogm.datastore.mongodb.type.GridFS 的编解码器 - org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class org.hibernate.ogm.datastore.mongodb.type.GridFS MongoDB jodatime:org.bson.codecs.configuration.CodecConfigurationException:找不到类org.joda.time.DateTime的编解码器 - MongoDB jodatime: org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class org.joda.time.DateTime 找不到适合我的课程的编解码器 - Can't find a codec for my class MongoDB 的不可变自动生成存储库抛出“找不到接口的编解码器” CodecConfigurationException - Immutables Autogenerated repository for MongoDB throws "Can't find a codec for interface" CodecConfigurationException MongoDB Java 插入引发 org.bson.codecs.configuration.CodecConfigurationException:找不到类 io.github.ilkgunel.mongodb.Pojo 的编解码器 - MongoDB Java Inserting Throws org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class io.github.ilkgunel.mongodb.Pojo GridFS:找不到自定义类的编解码器 - GridFS: Can't find a codec for custom class 找不到类org.json.JSONArray的编解码器 - Can't find a codec for class org.json.JSONArray
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM