Spring Data Mongo - 如何映射继承的 POJO 实体?

2024-03-11

我对 Spring 还很陌生,但我想在这个项目上尝试一下。 我有一个 MongoDB 数据库,其中填充了相当复杂的文档。我想使用 Spring data Mongo 来查询(没有其他 CRUD 操作)数据库。

我已经使用 POJO 描述了我的文档实体,但其中一些是抽象的(请参阅GeometryGeoJSON用于接受所有类型的 GeoJson 几何图形,或者Contact那可以是一个Person or an Organisation。下面提供了 GitHub 存储库的链接)。

使用该实体定义进行测试,java.lang.InstantiationError抛出这个问题是公平的,因为这些抽象类中没有定义构造函数。

Here is GitHub 存储库 https://github.com/charlycou/spring-mongo-test如果您需要看一下。

我对这一切感到有点迷失,但我会更仔细地查看文档。

你会如何面对这个问题?


我会回答我自己的问题。正如评论中提到的,解决方案是使用Converter.

这是我打算用我的类模型实现的示例:

A Contact可以是Person or an Organisation.

如果您使用的是 spring-data-mongodbMongo存储库 https://docs.spring.io/spring-data/mongodb/docs/current/api/org/springframework/data/mongodb/repository/MongoRepository.html根据实体模型将数据写入数据库,_class字段将被添加到文档根和复杂属性类型(请参阅本节 https://docs.spring.io/spring-data/data-mongodb/docs/current/reference/html/#mongo-template.type-mapping)。该字段存储 Java 类的完全限定名称,并且在从 MongoDb 文档映射到 Spring 数据模型时可以消除歧义。

如果您的应用程序只是从数据库中读取文档(没有_classfields),你需要告诉 Spring data 在映射时要实例化哪个类Contact。 Spring-data 允许您使用自定义默认类型映射行为Converter。使用显式Converter 覆盖类的默认映射 https://docs.spring.io/spring-data/mongodb/docs/2.1.2.RELEASE/reference/html/#mapping-explicit-converters。你需要明确地映射你的整个类。这是我的一个例子联系阅读转换器:

@ReadingConverter
public class ContactReadConverter implements Converter<Document, Contact> {

    @Override
    public Contact convert(Document source) {
        if (source.get("firstName") == null) {
            Organisation organisation = new Organisation();
            I18n name = new I18n();
            name.setEn(source.get("name", Document.class).get("en", String.class));
            name.setFr(source.get("name", Document.class).get("fr", String.class));
            organisation.setName(name);
            organisation.setAcronym(source.get("acronym", String.class));
            organisation.setRole(source.get("role", String.class));
            return organisation;
        }
        Person person = new Person();
        person.setFirstName(source.get("firstName", String.class));
        person.setLastName(source.get("lastName", String.class));
        person.setRole(source.get("role", String.class));
        person.setEmail(source.get("email", String.class));
        person.setOrcId(source.get("orcId", String.class));
        if (source.get("organisation") != null) {
            Document sourceOrg = source.get("organisation", Document.class);
            Organisation organisation = new Organisation();
            organisation.setAcronym(sourceOrg.get("acronym", String.class));
            organisation.setRole(sourceOrg.get("role", String.class));
            if (sourceOrg.get("name") != null) {
                I18n name = new I18n();
                name.setFr(sourceOrg.get("name", Document.class).get("fr", String.class));
                name.setEn(sourceOrg.get("name", Document.class).get("en", String.class));
                organisation.setName(name);
            }
            person.setOrganisation(organisation);
        }
        return person;
    }
}

然后,需要注册新定义的转换器:

@Configuration
public class DataportalApplicationConfig extends AbstractMongoConfiguration {
    @Value("${spring.data.mongodb.uri}")
    private String uri;
    @Value("${spring.data.mongodb.database}")
    private String database;
    @Override
    public MongoClient mongoClient() {
        return new MongoClient(new MongoClientURI(uri));
    }
    @Override
    protected String getDatabaseName() {
        return database;
    }    
    @Bean
    @Override
    public MongoCustomConversions customConversions() {
        List<Converter<?, ?>> converterList = new ArrayList<>();
        converterList.add(new ContactReadConverter());
        return new MongoCustomConversions(converterList);
    }
}

希望能帮助到你。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring Data Mongo - 如何映射继承的 POJO 实体? 的相关文章

随机推荐

  • Kafka:多个实例中的单个消费者组

    我正在致力于为我们的应用程序实施基于 Kafka 的解决方案 根据 Kafka 文档 我的理解是消费者组中的一个消费者 即一个线程 在内部映射到订阅主题中的一个分区 假设我有一个包含 40 个分区的主题 并且有一个在 4 个实例中运行的高级
  • 它们真的是虚拟代码吗?

    某些按键的虚拟按键代码 例如移位 Del 等与 C C 相比 在 java 中显示为不同的值 例如 Key Java C C Shift 16 160 91 219 93 221 92 220 Del 127 46 Window 524 9
  • 如何为另一个类型类中的所有类型编写实例?

    我必须定义一个类型类Truthy其中包含一个方法true将类型类的实例转换为Bool value 我的类型类声明 class Truthy a where true a gt Bool 接下来 我必须为各种类型定义此类的实例 包括列表和数字
  • 这段代码使用 wstring 和 MultiByteToWideChar 安全吗?

    Using std wstring我现在的样子MultiByteToWideChar std wstring widen const std string in int len MultiByteToWideChar CP UTF8 0 i
  • Pandas:将列的值分配给字典值设置的限制

    我怎样才能删除iterrows 使用 numpy 或 pandas 可以更快地完成此操作吗 import pandas as pd import numpy as np df pd DataFrame A foo bar foo bar f
  • 获取没有滚动条的UITableView的高度

    我需要获得一个的完整高度UITableView 即没有更多内容可滚动的高度 有什么办法可以做到这一点吗 我试过了 tableView sizeThatFits CGSizeZero 但只返回 0x0CGSize Try the conten
  • GitHub 项目最新版本的下载链接

    我正在尝试向我的网站添加一个项目最新 github 版本的下载链接 例如链接https github com mongodb mongo archive r3 0 0 rc7 zip https github com mongodb mon
  • 无法恢复几何备份 MySQL 5.7 错误

    我一直在从 Mysql 升级网站5 6 to 5 7 当从以下位置恢复备份时mysqldump 在Mysql 5 1 5 6下工作了10年 不变 在MySQL下不再工作5 7 具体来说 第一行几何数据恢复失败 ERROR 1416 2200
  • 特殊字符(夏威夷语“Okina”)导致奇怪的字符串行为

    The 夏威夷语报价 https en wikipedia org wiki CA BBOkina当 T SQL 与字符串函数结合使用时 它会出现一些奇怪的行为 这里发生了什么 我错过了什么吗 其他角色是否也遇到同样的问题 SELECT U
  • 打包时只生成一场战争

    默认情况下 JHipster 在打包阶段生成 2 个 war your project version war 和 your project version war original 第一个是可执行 jar 第二个是可以在 servlet
  • Clojure 中如何泄漏内存?

    为了周四在湾区 Clojure 聚会上的演讲 我正在整理一份 Clojure 中泄漏内存的方法列表 到目前为止我有 抓住无限序列的头部 通过在循环中调用 lambda 创建大量泛型类 这仍然是一个问题 保存对未使用数据的引用 还有什么 通过
  • 显式遵守 Codable 删除了结构上的成员初始化程序生成

    Given struct Foo let bar Bar 我得到了一个方便的初始化程序来使用 let foo Foo bar Bar But if Bar不是它本身Codable 或者由于某些其他原因我需要明确实现Codable on Fo
  • React - 反应脚本 publicPath

    是否有可能覆盖开发环境的反应脚本中的 publicPath 我使用 symfony 并且在 twig 中包含了 React 应用程序 所以我必须更改资产来提供服务http localhost 3000 static js bundle js
  • SetWindowPos() 函数不移动窗口?

    我有一个对话框 我想将其放置在另一个对话框中 并相对于主对话框上的其中一个控件进行定位 void CspAceDlg DrawResultsArea CWnd pTabCtl GetDlgItem IDC BUILDTABS CRect r
  • 由于 GCM SenderId Android 无法生成 APK 版本

    我在我的应用程序中实现了 GCM Google Cloud Messaging Google Play 服务库已自动生成values xml其中我的senderId is
  • 如何在android VideoView中显示Youtube视频? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我正在使用 android 应用程序
  • 使用 Jquery 更改选择值

    我正在尝试使用 Jquery 更改表单中 选择 输入的值 但是当它更改时 该更改的函数不起作用 HTML
  • servlet 的根 URl

    我想从其中一个 servlet 获取 Web 应用程序的根 url 如果我将应用程序部署在 www mydomain com 中 我想获得像 http www mydomain com http www mydomain com 同样的事情
  • 使用 Neo4j 的 Cypher 返回我的朋友和朋友的朋友

    我有具有双向关系的节点 如下 我正在尝试创建一个查询 我想返回特定节点的所有后续节点及其后续节点的后续节点 3 希望深度 例如假设这些关系 gt 符号跟随 A gt B B gt A B gt C C gt B C gt D D gt C
  • Spring Data Mongo - 如何映射继承的 POJO 实体?

    我对 Spring 还很陌生 但我想在这个项目上尝试一下 我有一个 MongoDB 数据库 其中填充了相当复杂的文档 我想使用 Spring data Mongo 来查询 没有其他 CRUD 操作 数据库 我已经使用 POJO 描述了我的文