ModelMapper:根据Child类选择映射

2024-01-21

TL;DR

我想以从 AbstractParent 映射到 AbstractParentDTO 的方式使用 modelMapper,然后在 ModelMapper-Config 中调用每个子类的特定映射器,然后跳过其余的(抽象类)映射。

这怎么可能?这是正确的方法吗?是否存在设计缺陷?


我拥有的:

父实体:

@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "type")
public abstract class Parent {
//some more fields
}

一个子实体:

//Basic Lombok Annotations
@DiscriminatorValue("child_a")
public class ChildA extends Parent {
//some more fields
}

另一个子实体:

@DiscriminatorValue("child_b")
public class ChildB extends Parent {
//some more fields   
}

然后我有父 DTO 类:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME)
@JsonSubTypes({
@JsonSubTypes.Type(value = ChildA.class, name = "child_a"),
@JsonSubTypes.Type(value = ChildB.class, name = "child_b"),
public abstract class ParentDTO {
//some more fields
}

一孩 DTO:

public class ClassADTO extends ParentDTO {
//some more fields
}

和另一个 DTO:

public class ClassBDTO extends ParentDTO {
//some more fields
}

就我而言,我将从控制器获取 DTO,并在将它们提供给服务时将它们映射到实体。我必须在 5-6 个端点中做同样的事情。

端点大致如下所示:

@PreAuthorize(CAN_WRITE)
@PutMapping("/{id}")
public ResponseEntity<ParentDTO> update(
        @PathVariable("id") UUID id,
        @RequestBody @Valid ParentDTO parentDTO) {

    Parent parent = parentService.update(id, parentDTO);

    if (parentDTO instanceof ChildADTO) {
        return ResponseEntity.ok(modelMapper.map(parent, ChildADTO.class));
    } else if (parentDTO instanceof ChildBDTO) {
        return ResponseEntity.ok(modelMapper.map(parent, ChildBDTO.class));
    }
    throw new BadRequestException("The Parent is not Valid");
}

只是我还有几个孩子让事情变得更加笨重。


我想要的是:

我不想多次检查 DTO(或实体)是什么实例,而是只想写:

modelmapper.map(parent, ParentDTO.class)

并在我的 ModelMapper 配置中检查一次“...的实例”。


我尝试过的:

我已经为 ModelMapper 配置中定义的每个可能的方向和映射情况提供了不同的转换器(因为它们无论如何都需要更复杂的映射)。

我尝试通过为父类再编写一个转换器并将其设置为 ModelMapper PreConverter 来解决我的问题:

    //from Entity to DTO
    Converter<Parent, ParentDTO> parentParentDTOConverter = mappingContext -> {
        Parent source = mappingContext.getSource();
        ParentDTO dest = mappingContext.getDestination();

        if (source instanceof CHildA) {
            return modelMapper.map(dest, ChildADTO.class);
        } else if (source instanceof ChildB) {
            return modelMapper.map(dest, ChildBDTO.class);
        } 
        return null;
    };

and:

modelMapper.createTypeMap(Parent.class, ParentDTO.class)
                .setPreConverter(parentParentDTOConverter);

但我总是遇到相同的 MappingError:

1) 实例化目标实例失败 com.myexample.data.dto.ParentDTO。确保这件事 com.myexample.data.dto.ParentDTOO 有一个非私有无参数 构造函数。

我得到(我猜),我无法构造抽象类的对象。但这不是我正在尝试的,不是吗? 我猜想 modelMapper 在完成我的 PreConverter 后仍在进行其余的映射。我也尝试使用 .setConverter 设置它,但总是得到相同的结果。


  • 有谁知道如何“禁用”自定义映射?我不 真的很想编写像映射器一样的“伪映射器” 为每个场景调用特定的映射器。

  • 我的设计很糟糕吗?你会如何改进它?

  • 这还没有实现到 ModelMapper 中吗?

任何帮助和提示表示赞赏。


嗯,我找到的解决方案使用转换器。在这种情况下modelMapper不尝试创建抽象类的新实例,而是直接使用转换器。

您可以将所有转换器放在同一个地方

modelMapper.createTypeMap(ChildA.class, ParentDTO.class)
            .setConverter(mappingContext -> modelMapper.map(mappingContext.getSource(), ClassADTO.class));

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

ModelMapper:根据Child类选择映射 的相关文章

随机推荐

  • 具有水平列的 DataGridView

    DataGridView 中是否可以有水平列 并且能够绑定这些列 您不必翻转 DataGridView翻转DataSet进行绑定 尝试这个 public DataSet FlipDataSet DataSet my DataSet Data
  • Common Lisp 循环

    在下面的循环中 let funs loop for i upto 3 do print i collect lambda i loop for fun in funs collect funcall fun 我直觉地认为我会得到一个包含四个
  • 通过 TFS 2015 部署 ASP.NET 5 (vNext)

    我们正在尝试使用新的工具链来构建 ASP NET 5 vNext CoreCLR 网站并将其部署到服务器集群 在新的编译更改和 TFS 更改之间 我不确定现在如何构建和部署所有内容 场景如下 用于源代码控制和构建代理的本地 TFS 以 Co
  • Elasticsearch,嵌套对象的存在过滤器不起作用

    我的映射是 properties user type nested properties id type integer is active type boolean null value false username type strin
  • 使用 Pow 运行 Rails 应用程序时,似乎无法从我的 iPhone 访问 .xip.io URL

    我尝试从 iPhone 5 访问使用 Pow 4 3 运行的 Rails 应用程序 但遇到了问题 如果我输入my app 192 168 2 11 xip io 它在我的开发机器上运行正常 即带有192 168 2 11局域网地址 在我的
  • getDrawable 返回 null

    因为我已经解决了关于这个问题的最后一个问题 因为我发布了与这个问题不同的代码 所以我将用正确的代码再次尝试 所以事情是这样的 我一直在使用适用于 Android 的 GoogleMaps API 运行一些测试 当我尝试使用我的一张图像在地图
  • jBoss CORS 支持,但有安全限制

    我正在使用网络常见的安全约束向我的 API 添加身份验证 但它似乎破坏了我的 CORS 过滤器 我之前只使用过过滤器 没有应用程序服务器级别的身份验证 基本思想是要求对除 rest account 端点下的请求之外的所有请求进行身份验证 因
  • 在 Emacs 中,other-window (C-x o) 的相反功能是什么? [复制]

    这个问题在这里已经有答案了 可能的重复 Emacs 切换到上一个窗口 https stackoverflow com questions 91071 emacs switch to previous window other window将
  • 将 NSString 转换为 NSDictionary

    有没有办法获得NSDictionary从通过其创建的字符串返回description method 鉴于此代码 NSDictionary dictionary NSDictionary dictionaryWithObjects NSArr
  • 启动外部扫描仪信息生成器时出错 - MingW 上的 gcc 链接问题

    启动外部扫描仪信息生成器时出错 MingW 上的 gcc 链接问题 启动外部扫描仪信息生成器时出错 sh c g E P v dD C Documents and Settings user1 workspace123 metadata p
  • Jenkins 持续交付管道根据输入跳过阶段

    简化的管道将类似于 1 build 2 unit test 3 deploy to dev 4 integration tests 5 deploy to prod 对于步骤 5 我设置了 Jenkins 管道输入命令 我们不会在每次提交时
  • 在 Javascript 中将 Uint8Array 转换为数组

    我有 Uint8Array 实例 其中包含某个文件的二进制数据 我想将数据发送到服务器 它将被反序列化为 byte 但是如果我发送 Uint8Array 就会出现反序列化错误 所以 我想将它转换为数组 因为数组反序列化得很好 我这样做 fu
  • Reactjs :状态的 ShouldComponentUpdate

    我该如何使用shouldComponentUpdate对于各州 我可以检查 shouldComponentUpdate nextProps nextState return this state value nextState value
  • 找不到函数plot.gam

    我正在阅读 R 中应用统计学习简介 ISLR 我被困在第 295 页上的部分 即广义加性模型实验室 当我运行以下代码时出现错误Error in plot gam gam1 se TRUE col red could not find fun
  • 如何在 Intellitrace Events 中跟踪异步数据库操作?

    我正在尝试查看我的应用程序使用的一些查询实体框架做 在我的方法中不是async我可以正常看到查询 public List
  • 如何获取 msbuild.exe?未安装VS2008时可以构建.vcproj吗?

    我知道如果我安装 Visual Studio 2005 或 2008 将会安装 msbuild 我知道如果我安装 NET Framework SDK 也会安装 msbuild 从 NET 3 0开始 我认为不再有单独的 NET Framew
  • Crontab 无法在 Mac OS 上运行 python

    我已经找到了我能找到的每一个答案并尝试了一切 但我仍然无法让我的 crontab 运行 python 我什至创建了一个 shell 脚本来运行 python 认为隔离会有所帮助 但它仍然不起作用 我在 crontab 中有以下条目 echo
  • 如何只输出第一行的git日志?

    我正在尝试自定义格式git log 我希望所有提交都显示在一行中 每行应该只显示提交消息的第一行 I 发现 http book git scm com 3 reviewing history git log html that git lo
  • 图像背景透明GIMP [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我有一些 jpg 图像 我需要有一个透明的背景 我将在网页中添加这些图像 并且我只需要查看图像的主要元素和下面的网页 有谁知道如何将图像转换为透明背景
  • ModelMapper:根据Child类选择映射

    TL DR 我想以从 AbstractParent 映射到 AbstractParentDTO 的方式使用 modelMapper 然后在 ModelMapper Config 中调用每个子类的特定映射器 然后跳过其余的 抽象类 映射 这怎