【问题标题】:Add new child entity to managed entity with MapStruct使用 MapStruct 将新的子实体添加到托管实体
【发布时间】:2020-05-28 04:23:59
【问题描述】:

我有一个 REST 端点,可用于创建或更新元素。这些元素的 REST 表示通过 Mapstruct 映射到我的 JPA 实体。现在为了更新现有实体,我将 @MappingTarget 传递给此方法:

@Mapping(source = "id", target = "id", ignore = true)
public abstract Element resourceToElement(ElementResource resource, @MappingTarget Element element);

实体Element 与一个子实体是一对多的关系,我们就叫它Child。关系在Element 内部是这样映射的:

@OneToMany(cascade = ALL, mappedBy = "element", orphanRemoval = true, fetch = EAGER)
private Collection<Child> children = new ArrayList<>();

像这样在Child 内部,Element 也是Child 主键的一部分:

@ManyToOne(fetch = LAZY, optional = false)
@JoinColumn(name = "element_id")
@JsonManagedReference
@Id
private Element element;

现在由于 JPA 托管实体的性质,在从资源映射到实体期间,我在插入 Child 表期间收到以下错误:

NULL not allowed for column "ELEMENT_ID"

似乎是这样,因为Element 已经是我要传入的托管实体,所以每当我通过添加(非托管)子项来修改它时,它都会尝试保留该元素。现在,我认为我要做的是将父 Element 分别设置为每个孩子,以便它知道持续查询的 element_id。但是在映射过程中的什么时候我会这样做?或者有没有更聪明的选择,我根本不必这样做?

【问题讨论】:

  • 您可能还创建了ChildResource 对吧?如果是,是否包含element 字段?

标签: java spring jpa mapstruct


【解决方案1】:

您可以使用@AfterMapping 实现此目的。

@AfterMapping
protected void initializeChildElement(@MappingTarget Element element) {
    element.getChildren().forEach(child -> child.setElement(element));
}

或者另一种方式是使用@Context。它有点复杂,但它是在创建 Child 之后立即设置 element 字段,而不是遍历整个集合。

public Element resourceToElement(ElementResource resource, @MappingTarget Element element) {
    return resourceToElement(resource, element, element);
}

@Mapping(qualifiedByName = "ChildWithElement", target = "children")
protected abstract Element resourceToElement(ElementResource resource, @MappingTarget Element element, @Context Element context);

protected abstract Child childResourceToChild(ChildResource childResource);

@Named("ChildWithElement")
protected Child childResourceToChild(ChildResource childResource, @Context Element element) {
    Child child = childResourceToChild(childResource);
    child.setElement(element);
    return child;
}

【讨论】:

    猜你喜欢
    • 2023-03-14
    • 1970-01-01
    • 2017-09-17
    • 1970-01-01
    • 2015-03-17
    • 2010-09-29
    • 1970-01-01
    • 1970-01-01
    • 2012-03-12
    相关资源
    最近更新 更多