Создание оболочки для mongodb pojo с использованием generics

ОБНОВЛЕНИЕ 2: Думаю, я добился некоторого прогресса. Моя IDE намного больше довольна моим кодом, но у меня есть только одна последняя строчка, которая расстроена:

CodecRegistry pojoCodecRegistry = fromRegistries(MongoClient.getDefaultCodecRegistry(),
                fromProviders(PojoCodecProvider.builder().automatic(true).build()));
        MongoClientURI connectionString = new MongoClientURI("my-mongo-string");
        MongoClient mongoClient = new MongoClient(connectionString);
        MongoDatabase database = mongoClient.getDatabase("New");
        database = database.withCodecRegistry(pojoCodecRegistry);
        MongoCollection<? extends Person> collection = database.getCollection("people", this.getClass());
        collection = collection.withCodecRegistry(pojoCodecRegistry);
        collection.insertOne(this);

Я поменял имя моей «Коллекции» на «Человек», чтобы временно предотвратить столкновение с «Коллекцией» Java. Кажется, все хорошо, за исключением последней строчки, которая выдает ошибку: insertOne (capture<? extends Utils.Person>) in MongoCollection cannot be applied to (Utils.Person). «Это» относится к моему личному классу. Что я здесь делаю не так?

Обновлено: Исходный вопрос ниже. Я считаю, что теперь я решил, что лучше всего использовать дженерики. Однако у меня возникают проблемы с генерацией этих двух строк (при условии, что я правильно инициализировал базу данных):

MongoCollection<MyClass> collection = database.getCollection("SomeString", MyClass.class);

Как лучше всего это сделать? Кажется, Java не любит использовать .class в общем.

Исходный вопрос:

Поэтому я хочу воспользоваться возможностью драйверов MongoDB хранить PJOS. Пример здесь. Но я планирую хранить в базе данных несколько классов, и я не хочу, чтобы каждый раз заново вводить весь код подключения, а также не хочу копировать и вставлять, а затем незначительно изменять код для каждого класса. У меня была идея создать класс «Коллекция», а затем расширить его, но это не совсем так, как я планировал. Вот мой код:

public class Collection {
    private MongoCollection<Collection> collection;

    public Collection(){}

    public Collection(String databaseName){
        databaseName = databaseName.toLowerCase().replaceAll(" ", "");
        CodecRegistry pojoCodecRegistry = fromRegistries(com.mongodb.MongoClient.getDefaultCodecRegistry(),
                fromProviders(PojoCodecProvider.builder().automatic(true).build()));
        MongoClientURI connectionString = new MongoClientURI("my-mongo-connection-string");
        com.mongodb.MongoClient mongoClient = new com.mongodb.MongoClient(connectionString);
        MongoDatabase database = mongoClient.getDatabase(databaseName);
        database = database.withCodecRegistry(pojoCodecRegistry);
        collection = database.getCollection(this.getClass().getName(), Collection.class);
    }

    public Collection findOne(Document document){
        return collection.find(document).first();
    }

    public void save(){
        collection.insertOne(this);
    }

}

Как видите, я хочу иметь возможность передавать имя базы данных любому классу, который наследуется от этого класса (или что-то еще, что нужно сделать.), И чтобы мой код подключался к базе данных и находил или сохранял POJO соответствующего подкласса должным образом. Так, например, если бы у меня был класс Person с номером телефона, я мог бы просто расширить свой класс Collections и рассчитывать, что все будет работать. Прямо сейчас, когда я вызываю функцию сохранения в дочернем классе, он пытается сохранить родительскую коллекцию, и я получаю сообщение об ошибке Can't find a codec for class Utils.MongoDb.Collection. (класс My Collection находится в моем собственном пространстве имен Utils.MongoDb). Я что-то упускаю? Есть ли лучший способ сделать это? Единственный способ заставить это работать - это скопировать и вставить код из моего конструктора Collection в каждый класс и изменить его с помощью правильных переменных класса. Надеюсь, все это понятно. Заранее спасибо!

3
0
861
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ага! Я понял! Что мне нужно было сделать, так это создать и написать вспомогательный метод, чтобы я мог передать this как объект. Мне также пришлось выполнить приведение к общему типу T. Я знаю, что это непроверенное приведение, но я не совсем уверен, как бы я проверил его здесь. В любом случае это работает!

 public <T> void saveObj(T obj){
        String dbName = "New";
        MongoDatabase database = getMongoDatabase(dbName);
        MongoCollection<T> collection = (MongoCollection<T>) database.getCollection(obj.getClass().getSimpleName(), obj.getClass());
        collection.insertOne(obj);
    }

    public MongoDatabase getMongoDatabase(String dbName) {
        CodecRegistry pojoCodecRegistry = fromRegistries(MongoClient.getDefaultCodecRegistry(),
                fromProviders(PojoCodecProvider.builder().automatic(true).build()));
        MongoClientURI connectionString = new MongoClientURI("my-mongo-string");
        MongoClient mongoClient = new MongoClient(connectionString);
        MongoDatabase database = mongoClient.getDatabase(dbName);
        database = database.withCodecRegistry(pojoCodecRegistry);
        return database;
    }

У меня есть предупреждение для метода saveObj: Type safety: Unchecked cast from MongoCollection<capture#1-of ? extends Object> to MongoCollection<T>Java(16777761) Какие у вас были версии драйверов Java и mongo?

Sinan 20.03.2021 18:39

Другие вопросы по теме