Java Morphia Map/List 基于通用类型加载但不从继承给定类型的子 class 加载

Java Morphia Map/List loads based on the generic type but does not load from the sub class that inherits the given type

我一直在尝试保存和检索具有包含字符串和父 class 类型的 Map 对象的实体。

例如,

public interface MorphiaInterfaceThing {
    String returnsAString();
}

然后我会有一个 class 实现 MorphiaInterfaceThing 。

@Embedded
public class MorphiaTest implements MorphiaInterfaceThing {

    private String stringReturn = "Test"    

    @Override
    public String returnsAString() {
        return stringReturn;
    }

}

然后,我会有一个包含 Map 的实体。

@Entity
public class SampleEntity {
    @Embedded
    private Map<String, InterfaceExample> map

    public void test() {
        map.put("TestKey", new MorphiaTest());
    }

}

然后我实例化对象和 运行SampleEntity#test()。使用 Datastore#save(obj) 保存实体时,它工作正常。它将实体保存到文档中。

但是,当我尝试通过吗啡从数据库中检索 SampleEntity 时,它抛出了一个 java.lang.RuntimeException:org.mongodb.morphia.mapping.MappingException:没有可用的构造函数。

经过一些测试,比如将地图的通用类型从 Map 更改为 Map,我最终推测问题是由于 morphia 试图从给定的实例化通用类型(在本例中为 MorphiaInterfaceThing),而不是文档中存储的实际 class 类型 (MorphiaTest)。由于 MorphiaInterfaceThing 是一个接口,它没有构造函数,因此会抛出异常。

我现在的问题是,我如何才能强制 morphia 调用存储在地图、文档中的实际对象而不是通用类型本身(即方法、注释等)?如果那不可能,是否有任何其他替代方法来完成我正在尝试做的事情(在这种情况下,存储具有父类 class 的某种类型的地图)?

另外,我对 Morphia 有点陌生,所以任何关于 Morphia 的其他建议将不胜感激!

您使用的是哪个版本的吗啡?如果你在你的 @Embedded 声明中传递 useDiscriminator=true 应该给吗啡足够的信息来加载你的类型。

好吧,我终于得到了我想要的东西,只需要普通的 mongodb 驱动程序。我仍然不确定你打算如何在 2.x 的吗啡以下进行。不过在2.x以上,应该可以用evanchooly的回答:

What version of morphia are you on? If you pass useDiscriminator=true on your @Embedded declaration that should give morphia enough info to load your types.

如果你无法使用morphia 2.x及以下,你应该可以使用最新的驱动程序来添加一个pojo。 (我花了足够长的时间才意识到) 可以使用 CodecRegistry 并通过注册 ClassModel 并启用 class 模型的 discriminator 来完成。要保存和检索,您可以使用 MongoCollection<T>,其中 T 是您要保存的对象。

供参考: http://mongodb.github.io/mongo-java-driver/3.9/bson/pojos/#properties-with-abstract-or-interface-types