org.bson.codecs.configuration.CodecConfigurationException: не удается найти кодек для класса com.MyClass (проблема сериализации MongoJack) - PullRequest
0 голосов
/ 05 марта 2019

Недавно я столкнулся с интересной проблемой.Похоже, что основной причиной является сериализация MongoJack.У меня есть родительский класс, скажем - Животное с двумя подтипами: Кошка и Собака .И я хочу сохранить эти объекты в mongodb, а затем получить его.Вот следующий код для этого:

public class MongoJackTest {
    public static void main(String[] args) {
        MongoClient mongoClient = new MongoClient("127.0.0.1", 27017);
        MongoDatabase database = mongoClient.getDatabase("test");
        Cat cat = new Cat("cat", "Tom", "mouse");
        Dog dog = new Dog("dog", "Oscar", "Bob");

        getJacksonMongoCollection(database, Animal.class).insert(cat);
        getJacksonMongoCollection(database, Animal.class).insert(dog);

        List<Animal> result = new ArrayList<>();
        MongoCursor<Animal> cursor = getJacksonMongoCollection(database, Animal.class).find(new Document()).iterator();
        while (cursor.hasNext()) {
            result.add(cursor.next());
        }
        System.out.println(result);
    }

    private static JacksonMongoCollection getJacksonMongoCollection(MongoDatabase database, Class entityBaseClass) {
        return JacksonMongoCollection.builder().build(database.getCollection("test"), entityBaseClass);
    }
}

Некоторые DTO:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "type", visible = true)
@JsonSubTypes({
        @JsonSubTypes.Type(value = Cat.class, name = "cat"),
        @JsonSubTypes.Type(value = Dog.class, name = "dog")})
abstract class Animal {
    @Id
    private String id;
    private String type;
    private String name;

    public Animal() {
    }

    public Animal(String type, String name) {
        this.type = type;
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public String getType() {
        return type;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "Animal{" +
                "id='" + id + '\'' +
                ", type='" + type + '\'' +
                ", name='" + name + '\'';
    }
}

class Dog extends Animal {

    private String master;

    public Dog(){}

    public Dog(String type, String name, String master) {
        super(type, name);
    }

    public String getMaster() {
        return master;
    }

    @Override
    public String toString() {
        return super.toString() + ", master='" + master + '\'' +
                '}';
    }
}

class Cat extends Animal {

    private String toy;

    public Cat(){}

    public Cat(String type, String name, String toy) {
        super(type, name);
        this.toy = toy;
    }

    public String getToy() {
        return toy;
    }

    @Override
    public String toString() {
        return super.toString() + ", toy='" + toy + '\'' +
                '}';
    }
}

Таким образом, идея состоит в том, чтобы хранить животных в монго, передавая общий Animal классв JacksonMongoCollection.Джексон должен определить, какой объект использовать @ JsonSubTypes.Type.Но это не работает, я получил:

Exception in thread "main" org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class com.test.mongojack.Cat.
at org.bson.codecs.configuration.CodecCache.getOrThrow(CodecCache.java:46)
at org.bson.codecs.configuration.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:63)
at org.bson.codecs.configuration.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:37)
at org.mongojack.JacksonCodecRegistry.get(JacksonCodecRegistry.java:59)
at org.bson.BsonDocumentWrapper.asBsonDocument(BsonDocumentWrapper.java:63)
at com.mongodb.internal.operation.Operations.documentToBsonDocument(Operations.java:485)
at com.mongodb.internal.operation.Operations.bulkWrite(Operations.java:359)
at com.mongodb.internal.operation.Operations.insertOne(Operations.java:299)
at com.mongodb.internal.operation.SyncOperations.insertOne(SyncOperations.java:147)
at com.mongodb.client.internal.MongoCollectionImpl.executeInsertOne(MongoCollectionImpl.java:494)
at com.mongodb.client.internal.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:478)
at com.mongodb.client.internal.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:472)
at org.mongojack.JacksonMongoCollection.insert(JacksonMongoCollection.java:117)
at com.test.mongojack.MongoJackTest.main(MongoJackTest.java:22)

Так что похоже на проблему сериализации, потому что она не работает, когда я пытаюсь сохранить объекты, и работает нормально, когда я читаю их из БД.

Я исправил эту проблему, указав каждый тип при вставке:

 getJacksonMongoCollection(database, cat.getClass()).insert(cat);
 getJacksonMongoCollection(database, dog.getClass()).insert(dog);

Итак, вывод: десериализация отлично работает с классом Animal и преобразованием в подтиппо типу.Сериализация требует определенного класса для вставки / обновления.Кто-нибудь знает, как это сделать лучше?Не стесняйтесь оставлять комментарии.Есть идеи, почему мое первое решение не сработало?Спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...