Morphia InstantiationException с абстрактным классом @Embedded

Я использую Morphia с проектом Play Framework 2.1 и базой данных MongoDB, и у меня возникла проблема с получением некоторых данных.

У меня есть класс A, который и @Entity хранятся в коллекции. Но этот класс A имеет свойство @Embedded List, этот класс B является абстрактным и имеет несколько реализаций.

Но этот класс B также имеет свойство @Embedded ClassC, и этот класс C тоже является абстрактным и может иметь несколько реализаций.

Я не думаю, что эту структуру можно использовать «как есть» и что Morphia справится с ней. В моей базе объекты хранятся корректно, ошибок нет.

{
    "_id" : ObjectId("5163c9131a887c8e5aea8d5f"),
    "className" : "package.to.ClassA",
    "list" : [
        {
            "propClassB" : [
                {
                    "className" : "package.to.an.ImplementationOfClassB",
                    "propClassC" : {
                        "className" : "package.to.an.ImplementationOfClassC"
                    }
                }
            ]
        }
    ]
}

Класс A помечен @Entity,
Класс B помечен @Embedded (и @Polymorphic, но я не думаю, что он используется)
Класс C помечен @Embedded (и @Polymorphic тоже)

Я делаю что-то неправильно ? Спасибо за все !


person Lebowski    schedule 09.04.2013    source источник


Ответы (1)


Хорошо, ребята, я понял, в чем была моя проблема, и я никогда не ожидал, что это будет. Я нашел решение в группе Google для Morphia.

Это была проблема ClassLoader! Я смог сохранить свои объекты в базе данных, но через секунду я не смог получить ни один объект, выбрасывая ClassNotFoundException везде...

Решение состояло в том, чтобы «переопределить» DefaultCreator Morphia, чтобы предоставить загрузчик класса приложения Play в классе Global (что позволяет настраивать поведение приложения при его запуске с помощью (методы onStart() и onBeforeStart()).

Morphia morphia = applicationContext.getBean(Morphia.class);

// Configuring class loader.
morphia.getMapper().getOptions().objectFactory = new DefaultCreator() {
    @Override
    protected ClassLoader getClassLoaderForClass(String clazz, DBObject object) {
        return app.classloader();
    }
};

Обратите внимание, что я использую Spring Framework для загрузки экземпляра Morphia, но я видел, как кто-то делает new Morphia(), я думаю, что это тоже работает (не эксперт;))

Вуаля! Надеюсь, это поможет кому-то когда-нибудь!

person Lebowski    schedule 11.04.2013
comment
Спасибо, столкнулся с похожей проблемой. - person Samyam A; 30.04.2013