gpt4 book ai didi

spring-data-jpa - Spring Data 和 JPA 一对多与 MapStruct

转载 作者:行者123 更新时间:2023-12-05 09:17:01 26 4
gpt4 key购买 nike

我在 Config 和 ConfigHeaders 之间有一个一对多的关系。这是配置映射器:

@Mapper(componentModel = "spring", uses = {UserMapper.class, ConfigHeadersMapper.class})
public interface ConfigMapper extends EntityMapper<ConfigDTO, Config> {

@Mapping(source = "user.id", target = "userId")
ConfigDTO toDto(Config config);

@Mapping(source = "userId", target = "user")
@Mapping(target = "messages", ignore = true)
Config toEntity(ConfigDTO configDTO);

default Config fromId(Long id) {
if (id == null) {
return null;
}
Config config = new Config();
config.setId(id);
return config;
}
}

这是 ConfigHeadersMapper:

@Mapper(componentModel = "spring", uses = {ConfigMapper.class})
public interface ConfigHeadersMapper extends EntityMapper<ConfigHeadersDTO, ConfigHeaders> {

@Mapping(source = "config.id", target = "configId")
ConfigHeadersDTO toDto(ConfigHeaders configHeaders);

@Mapping(source = "configId", target = "config")
ConfigHeaders toEntity(ConfigHeadersDTO configHeadersDTO);

default ConfigHeaders fromId(Long id) {
if (id == null) {
return null;
}
ConfigHeaders configHeaders = new ConfigHeaders();
configHeaders.setId(id);
return configHeaders;
}
}

当我尝试保存一个新实体(Config 和 ConfigHeaders 的 id 等于 null)时,这段代码:

final Config config = configMapper.toEntity(configDTO);
Config newConfig = configRepository.save(config);

保存 Config 和 ConfigHeaders,但 ConfigHeaders 中的 config_id (FK) 为 NULL。

所以我尝试了这段代码:

final Config config = configMapper.toEntity(configDTO);
config.getHeaders().stream().forEach(header -> header.setConfig(config));
Config newConfig = configRepository.save(config);

并且确实使用自动生成的父 ID (config_id) 保存子项 (ConfigHeaders)。

你能告诉我我在 MapStruct 上做错了什么吗?我对这个工具很陌生,我不认为这是正确的解决方案。我认为之前的代码目前只是一种解决方法。

实际上,我已经检查了已生成的 MapStruct 实现代码,我注意到它正确设置了父 ID(对于新 ID 为 null),但它没有设置与父实体的向后关系。我如何通过 MapStruct 完成此操作?

提前致谢

最佳答案

正如您所注意到的,为了让 JPA 正确执行保存,您需要在 ConfigHeader 中设置指向配置的链接。

有两种方法可以实现这一点:

第一个选项:

您可以使用 CollectionMappingStrategy#ADDER_PREFERRED(参见更多信息 here)。为此,您需要在 Config 中添加如下内容:

public void addHeader(ConfigHeader header) {
this.headers.add(header);
header.setConfig(this);
}

第二个选项:

您在 ConfigMapper 中使用 @AfterMapping 并在那里设置所有 header 的配置。

@AfterMapping
default void linkHeaders(@MappingTarget Config config) {
config.getHeaders().stream().forEach(header -> header.setConfig(config));
}

@sjaak 在 https://stackoverflow.com/a/48974119/1115491 中提出的第三个选项:

您可以使用 @Context 属性,如 mapstruct-jpa-child-parent 中所示例子。这与第一个选项具有相同的性能,因为您不必对 header 进行两次迭代。这样做的另一个好处是,您可以在无法向实体添加内容时使用它。

看起来像:

public class ConfigContext {
private Config config;
@BeforeMapping
public void setConfig(@MappingTarget Config config) {
this.config = config;
}

@AfterMapping
public void establishRelation(@MappingTarget ConfigHeader header) {
header.setConfig( header );
}
}

您还需要调整您的 toEntity 方法,以便它们也包含上下文。

关于spring-data-jpa - Spring Data 和 JPA 一对多与 MapStruct,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48967181/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com