首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

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

基础概念

Morphia 是一个用于 MongoDB 的 Java ORM(对象关系映射)库,它允许开发者将 Java 对象映射到 MongoDB 文档中,并提供了方便的 API 来进行数据库操作。在 Morphia 中,MapList 是常用的数据结构,它们可以用来存储和操作嵌套的文档数据。

相关优势

  1. 简化开发:Morphia 通过自动映射 Java 对象到 MongoDB 文档,减少了手动编写 CRUD 操作的代码量。
  2. 类型安全:使用泛型可以确保在编译时检查类型,减少运行时错误。
  3. 灵活性:Morphia 支持复杂的嵌套结构和自定义类型转换器,使得数据模型更加灵活。

类型

  • Map:键值对集合,键通常是字符串,值可以是任意类型。
  • List:有序集合,可以存储多个相同类型的元素。

应用场景

  • 数据存储:将 Java 对象持久化到 MongoDB 数据库中。
  • 数据查询:通过 Morphia 提供的 API 进行复杂的数据查询和聚合操作。
  • 数据转换:在 Java 对象和 MongoDB 文档之间进行自动转换。

问题描述

在使用 Morphia 时,可能会遇到一个问题:基于泛型类型加载 MapList,但不从继承给定类型的子类加载。这意味着如果你有一个基类和一个子类,Morphia 只会加载基类的 MapList,而不会加载子类的。

原因

这个问题通常是由于 Morphia 的类型擦除机制导致的。Java 的泛型在编译时会进行类型擦除,这意味着在运行时,Morphia 无法获取到具体的泛型类型信息,只能获取到原始类型。

解决方法

  1. 使用注解:通过 @Property@Type 注解来明确指定泛型的具体类型。
代码语言:txt
复制
@Entity
public class MyClass {
    @Property("myMap")
    private Map<String, MySubClass> myMap;

    // getters and setters
}
  1. 自定义类型转换器:实现 TypeConverter 接口来自定义类型转换逻辑。
代码语言:txt
复制
public class MySubClassConverter extends TypeConverter<MySubClass> {
    @Override
    public MySubClass decode(Class<?> targetClass, Object fromDBObject, MappedField optionalExtraInfo) {
        // 自定义解码逻辑
    }

    @Override
    public Object encode(MySubClass value, MappedField optionalExtraInfo) {
        // 自定义编码逻辑
    }
}

然后在 Morphia 中注册这个转换器:

代码语言:txt
复制
Datastore datastore = morphia.createDatastore(new MongoClient(), "database");
datastore.getMapper().getConverters().addConverter(new MySubClassConverter());
  1. 使用具体类型:尽量避免使用泛型,而是使用具体的类型。
代码语言:txt
复制
@Entity
public class MyClass {
    private Map<String, MySubClass> myMap;

    // getters and setters
}

参考链接

通过以上方法,可以解决 Morphia 在加载 MapList 时无法从继承给定类型的子类加载的问题。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

3小时Java入门

多态具有一个非常强大功能,就是允许添加更多类型子类实现功能扩展,却不需要修改基于父类代码。 这就实现了面向对象编程非常著名开闭原则:对扩展开放,对修改封闭。 ? ? ?...5,获取继承关系 ? ? 二十五, 就是编写模板代码来适应任意类型Java容器类中大量使用了好处是使用时不必对类型进行强制转换,它通过编译器对类型进行检查。...Java实现是使用擦拭法,编译器编译包含类时将换成Object类型, 编译器编译实例化代码时根据具体类型进行安全转型,而JVM虚拟机对一无所知。...因此类型不能是int,float,double等基本类型,并且不能够获取反射。 ? ?...Java中用尖括号来表示,Scala中用方括号来表示Java数组用花括号来表示,Scala中一般用工厂方法。

2.7K30

Java基础

集合相关问题List,Set,Queue,Map四种集合特点和区别在 Java 中,List、Set、Queue 和 Map 是常用集合接口,它们各自具有不同特点和用途:List(列表):允许重复元素...Java含义本质是参数化类型,也就是说所操作数据类型被指定为一个参数适用场景:写一个排序方法,能够对整型数组、字符串数组甚至其他任何类型数组进行排序,该如何实现?...答案是:可以使用 Java 。使用 Java 概念,我们可以写一个方法来对一个对象数组排序。然后,调用该方法来对整型数组、浮点数数组、字符串数组等进行排序。...extends Number>来定义,如此定义就是通配符值接受Number及其下层子类类型类型通配符下限通过形如 List<?...多态性使得可以在不同对象上使用相同方法名,根据对象实际类型,可以产生不同行为方法重写(Override):多态性基于方法重写。子类可以根据自身需求重写(覆盖)父类方法。

22820
  • Retrofit解析3之反射

    例如,Mapl类允许您向一个Map 添加任意类对象,即使最常见情况是在给定映射(map)中保存某个特定类型(比如 String) 对象。...在生成Java字节码中是不包含类型信息。使用时候加上类型参数,会被编译器在编译时候去掉。这个过程就叫做类型擦除。...来表示位置类型,比如List就声明了List中包含元素类型是未知。通配符所代表其实是一组类型具体类型是未知List 所声明就是所有类型都是可以。但是List<?...因为虽然类型未知,肯定是Object及其子类。 (六) 使用注意事项: 在使用时候可以遵循一些基本原则,从而避免一些常见问题。 在代码中避免类和原始类型混用。...(七) 与反射 1、Java与反射结构 java中class,method,field继承体系 ? Paste_Image.png java中所有对象类型定义类Type ?

    1.2K20

    java核心技术第六篇之断言、日志、包装类型和工具类

    8 简化,出现菱形 9 异常多个catch合并,每个异常用或| 10 try-with-resources 语句 JDK1.8 新特性: 一、接口默认方法:Java 8允许我们给接口添加一个非抽象方法实现...接口与多继承 1. 可以让子类继承主要类型,让次要类型作为一个接口让子类实现. 2. 单继承具备简单性(相对于多继承),使用接口实现继承并不会破坏其简单性 2....Set需要注意写法: 例: Set> set = map.entrySet(); 键值对类型为:Map.Entry , 例...类型 ↑↑以上是JDK5.0之前没出时候做法 加之后,不需要在强转了 2....Properties限定,只能装String类型数据(name,value) 4.

    85210

    Java JDK1.5: 新特性讲解说明

    继承体现关于父类中含有 对应子类对父类处理情况:如下父类有子类继承父类:不保留父类中,擦除了父类中(默认是 Object)// 父类class Father...父类有子类继承父类:并指明了父类(具体类型) 注意: 由于子类继承父类/实现接口时,指明了具体是什么类型,所以实例化子类对象时,不再需要指明了。...}父类有子类继承父类:并保留了父类(并没有指明具体类型)注意: 因为子类并没有指明父类具体类型,所以子类要沿用上父类从而对父类上(赋予具体类型),不然编译无法通过。...Father { }父类有子类继承父类:并保留了父类部分(部分指明了父类具体类型,部分没有指明父类具体类型),外加子类定义自己独有的注意: 因为子类并没有指明父类具体类型...// 父类class Father {}// 父类有子类继承父类:并保留了父类`部分`(部分指明了父类具体类型,部分没有指明父类具体类型),外加子类定义自己独有的

    94500

    JavaSE笔记

    : 将类型由原来具体类型参数化,然后在使用/调用时传入具体类型 这种参数类型可以用在类、方法、和接口中,分别被称为类、方法、接口 定义格式 :指定一种类型格式,这里类型可以看成是形参...这里类型可以看成是形参 将来具体调用时候给定类型可以看成是实参,并且实参类型只能是引用类型数据 类定义格式 修饰符 class 类名 {}; 方法定义格式 修饰符 返回值类型...方法名(类型 变量名){} 接口定义格式 修饰符 interface 接口名{} 类型通配符 为了表示各种List父类,可以使用通配符 类型通配符: List:表示元素类型未知List,它元素可以匹配任何类型 这种通配符List仅表示它是各种List父类,并不能把元素添加到其中 类型通配符上限:<?...,如果我们指定了接口是什么类型,那么接口中get()方法就会生产什么类型数据提供我们使用 Consumer接口 Consumer :包含两个方法 void accept(T t):对给定参数执行操作

    1.3K21

    Java学习知识笔记

    final类不能被继承,即不能有子类,final方法不能被子类重写 19 list结合子类特点: Arraylist:底层数据结构是数组,查询速度快,增删速度慢 有序,可重复 linkedList...参考enumerable.java 24 hashmap 25 对于不同类型对象进行同一事件解决。比如说人和熊猫都要吃饭,人是一顿,熊猫是多少根竹子。...参考thing.java,定义单词不一样。 26 序列化,反序列化 前者将对象转换成字节流,后者将字节流换成对象,子类也可以进行序列化,对于静态属性字段不可以序列化,它不是对象。...返回一个组合Consumer。一次执行此操作,然后进行after操作,接口,两次连续操作只公用原始数据。...不会套接上一个消费之后数据 3 Supplier接口 接口 boolean test(T t)对给定参数进行判断,判断逻辑有lanmbda表达式实现,返回一个布尔值。

    8210

    Java基础八股文(背诵版)

    多重继承会使类型转换、构造方法调用顺序变得复杂,会影响到性能。 简述 Java 多态 Java 多态可以分为编译时多态和运行时多态。...简述 Object 类常用方法 hashCode:通过对象计算出散列码。用于 map 或 equals 方法。需要保证同一个对象多次调用该方法,总返回相同整型值。...当垃圾回收器准备好释放对象占用空间时,首先会调用 finalize()方法,并在下一次垃圾回收动作发生时真正回收对象占用内存。 简述 ,即“参数化类型”,解决不确定对象具体类型问题。...在使用过程中,操作数据类型被指定为一个参数,这种参数类型在类中称为类、接口中称为接口和方法中称为方法。...简述擦除 Java 编译器生成字节码是不包涵信息类型信息将在编译处理是被擦除,这个过程被称为擦除。 简述注解 Java 注解用于为 Java 代码提供元数据。

    44.8K2738

    精选Java基础面试120题

    2.20 请简述是什么?有什么用?在哪里用? 是什么?是一种特殊类型,它把指定类型工作推迟到客户端代码声明并实例化类或方法使用进行。...好处 提高了程序安全性 将运行期遇到问题转移到了编译期 省去了类型强转麻烦 常见应用 方法 接口 2.21 如何编写一个方法,让它能够接受参数并返回类型?...并举例 方法,指把定义在方法上,使用类型来替代原始类型 public static T[] sort(T[] t){ Arrays.sort(t); return t; } 2.22...请简述Java中如何使用编写带有参数类?...extends T :代表接收类型为T类型或T子类类型 List向上限制? super T :代表接收类型为T类型或T父类类型 7.9 请简述Set集合特点?

    78120

    java通配符 T,E,K,V,?

    若文章内图片失效(无法正常加载),请留言反馈或直接联系我。...java java(generics)是jdk5引入新特性,提供了编译时类型安全检测机制,该机制运行开发者在编译时检测到非法类型....本质是参数化类型,也就是说,将所操作数据类型作为一个参数传递,通过这个类型参数,就能识别这个变量类型 public class TestGeneric { private T...K和V 表示key,value,比如用于map通配符 T(type) 表示具体一个java类型 E (element) 表示一个元素,例如List 除了这几个特定意义通配符之外,还存在 ?...super E> 下界: 用 super 进行声明,表示参数化类型可能是所指定类型,或者是此类型类型,直至 Object private void test(List<?

    66210

    Q&A:Java

    Java语言中,多态就是指程序中定义引用变量所指向具体类型和通过该引用变量发出方法调用在编程时并不确定,而是在程序运行期间才确定, 在Java中实现多态三个必要条件:继承、重写、向上转型。... 提供编译时类型安全检测机制,通过参数可以指定传入对象类型,编译时可以对参数进行检测 擦除:信息只存在于代码编译阶段,在进入 JVM 之前,与相关信息会被擦除掉。...Java编译器是通过先检查代码中类型,然后在进行类型擦除,再进行编译。 编译时,检查添加元素类型,更安全,减少了类型转换次数,提高效率。...比如原生List返回类型是Object对象,需要手动转换类型才能使用,使用后编译器自动转换 类、接口、方法 支持通配符 :支持任意类型 :支持A类以及A类子类,规定了上限 <?

    62620

    Java基础题

    1、JAVA几种基本数据类型是什么,各自占用多少字节。 ? 2、String类能被继承吗,为什么 不能。...25、在jdk1.5中,引入了存在是用来解决什么问题。...面向对象转型只会发生在具有继承关系子类中(接口也是继承一种) 向上转型:其核心目的在于参数统一上,根本不需要强制类型转换。...不过呢,在JDK1.5之后,新增加了技术,这就将上述向下转型问题消灭在了萌芽之中。...核心意义在于:类在进行定义时候可以使用一个标记,此标记就表示类中属性或者方法以及参数类型,标记在使用时候,才会去动态设置类型。 26、JavaHashSet内部是如何工作

    1K10

    记录(三)

    具体可以看以前转一篇文章:关于一次List面试 之前写过ArrayList相关内容:ArrayList扩容机制 1.4 讲讲类实例化顺序,比如父类静态数据,构造函数,字段,子类静态数据,构造函数...代码验证可以看这个:Java基础-类实例化顺序 1.5 用过哪些 Map 类,都有什么区别,HashMap 是线程安全吗,并发下使用 Map是什么,他们内部原理分别是什么,比如存储方式,hashcode...LinkedHashmap是基于链表来实现数据插入有序。 1.8 抽象类和接口区别,类可以继承多个类么,接口可以继承多个接口么,类可以实现多个接口么。...继承 指的是一个类(称为子类、子接口)继承另外一个类(称为父类、父接口)功能,并可以增加它自己新功能能力,继承是类与类或者接口与接口之间最常见关系;在Java中此类关系通过关键字extends...3.6 在 jdk1.5 中,引入了存在是用来解决什么问题。 主要针对向下转型时所带来安全隐患,其核心组成是在声明类或接口时,不设置参数或属性类型

    40410

    Java基础-甲骨文系列

    简述 ,即“参数化类型”,解决不确定对象具体类型问题。在编译阶段有效。...在使用过程中,操作数据类型被指定为一个参数,这种参数类型在类中称为类、接口中称为接口和方法中称为方法。...简述擦除 Java编译器生成字节码是不包涵信息类型信息将在编译处理时被擦除,这个过程被称为擦除。...动态代理实现方式 包括两种方式:基于接口继承基于继承 利用JDK反射机制,实现代理接口。 利用CGLib,对指定类生成子类,进行代理。...Java集Collection类型 链表List:ArrayList, Vector, LinkedList 集合Set:Hashset, LinkedHashSet, TreeSet 表Map:HashMap

    84510

    Kotlin入门潜修之类和对象篇—及其原理

    因为map2值只能是Integer,所以返回是Integer,而不是String } java中既支持类也支持方法。...无界通配符可以接受任意类型赋值;子类限定通配符可以接受类型为其子类、本身或者没有类型赋值,其中没有类型赋值时会有编译警告。...所谓协变就是只要参数类型具有继承关系就认为整个类型也有“继承”关系:比如上例中,String继承于Any,那么我们就可以认为IList是IList子类型,这样就可以让IList...in修饰符允许我们写 } 这种情况叫做逆变,即我们当类型参数具有继承关系时候,我们可以认为整个也有继承关系,而使用in修饰后,可以允许父类型变量赋值于子类型变量,如上面代码中,将Comparable...threshold }.map { it.toString() } } 原理 kotlin中java一样,都是“假”,为什么这么说?

    92830

    Java高级特性入门——、反射和注解!

    一言以蔽之,就是通过类型参数化,来解决程序通用性设计和实现若干问题。 Java是1.5版本后引入特性,它主要被用于解决三类问题: 1、编译器类型检查 ?...乍一看类型变量这个词,感觉有点晦涩难懂,其实如果仔细思量一番会发现它其实并不难理解,上面的实例4可以理解为“在使用时,可以将类型参数T传递给Box类型本身”,结合Oracle给出官方定义“本质是类型参数化...对于实例3,如果不使用,当一个不清楚业务场景的人在对集合进行操作时,无法知道list中存储是什么类型对象,如果使用了,就能够通过其类型参数判断出当前业务场景,也增加了代码可读性,同时也可以大胆地在抽象继承基础上进行开发了...通配符设计存在一定场景,例如在使用后,首先声明了一个Animal类,而后声明了一个继承自Animal类Cat类,显然Cat类是Animal类子类,但是List却不是List子类型,而在程序中往往需要表达这样逻辑关系...如上图中第一个例子,第三个add()操作会受限,原因在于ListListList子类型

    98830

    一文打通java

    从JDK1.5以后,Java引入了“参数化类型(Parameterized type)”概念, 允许我们在创建集合时再指定集合元素类型,正如:List,这表明 该List只能保存字符串类型对象。...12.父类有子类可以选择保留也可以选择指定类型子类不保留父类:按需实现 class Father { } 没有类型 擦除 // 子类不保留父类 // 1...(子类或者子接口),而G是具有声明 类或接口,G并不是G子类型!...比如:String是Object子类,但是List并不是List子类。  通配符使用 基本介绍 1.使用类型通配符:? 比如:List ,Map Lis<?...允许所有引用调用 通配符指定上限 上限extends:使用时指定类型必须是继承某个类,或者实现某个接口,即<= 通配符指定下限 下限super:使用时指定类型不能小于操作类,即>

    16930

    详解GsonTypeToken原理

    擦除 众所周知,Java只在编译时有效,到了运行时这个类型就会被擦除掉,即ListList在运行时其实都是List类型。...Java类库是Java生态中非常宝贵财富,必须保证向后兼容(即现有的代码和类文件依旧合法)和迁移兼容(代码和非代码可互相调用)基于上面这两个背景和考虑,Java设计者采取了"类型擦除"这种折中实现方式...正如上面说,如果直接把List>类型传过去,但是因为运行时被擦除了,所以得到其实是List,那么后面的Gson就不知道要转成Map<String...大家都知道,在Java语法中,在这个语境,{}是用来定义匿名类,这个匿名类是继承了TypeToken类,它是TypeToken子类。 为什么要通过子类来获取类型?...ParameterizedType是表示带有参数类型Java类型,JDK1.5引入了之 后,Java中所有的Class都实现了Type接口,ParameterizedType则是继承了Type

    5.4K22

    Kotlin 范之协变、逆变

    类(Class) 与类型(Type) Kotlin 中类和类型是不一样概念。 下图充分展示了它们区别。 ? class vs type.png 二. 变是指类型转换后继承关系。...如果 Dog 是 Animal 子类 List 并不是 List 子类。...extends Animal> 子类型。即 animals 变成了可以放入任何 Animal 及其子类 List。 因此,下面的代码编译是正确List<?...2.3 不变 默认情况下,Kotlin 中类是不变。 这意味着它们既不是协变也不是逆变。 例如 MutableList,它可读可写,没有使用in、out。 三....总结 本文从 Kotlin 类、类型引出了变。介绍了 Kotlin 协变、协变和不变概念和特性,以及 Java 上界通配符、下界通配符。 该系列相关文章: Kotlin 类型擦除

    1.3K50
    领券