当前位置: 首页 > 知识库问答 >
问题:

使用mapstruct映射Hibernate实体

姚昊焱
2023-03-14

我对这些技术是新的,所以提前道歉。

我在我的应用程序中使用了springboot、Spring JPA、hibernate和mapstruct。

    /**
     * Mapper class for the entity {@link Child} and its corresponding data transfer object {@link ParentTlDTO}.
     */
    @Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.WARN, uses = {ParentMapper.class})
    public interface ChildMapper extends EntityMapper<ChildDTO, Child> {

      @Mapping(source = "parent.id", target = "parentId")
      @Override
      ChildDTO toDto(Child child);

      @Mapping(source = "parentId", target = "parent.id")
      @Override
      Child toEntity(ChildDTO childDTO);

      default Child fromId(String id) {
        if (id == null) {
          return null;
        }
        Child Child = new Child();
        Child.setId(id);
        return Child;
      }
    }


    @Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE, uses = {})
    public interface ParentMapper extends EntityMapper<ParentDTO, Parent> {

      @Mapping(target = "childs", ignore = true)
      Parent toEntity(ParentDTO parentDTO);

      default Parent fromId(String id) {
        if (id == null) {
          return null;
        }
        Parent parent = new Parent();
        parent.setId(id);
        return parent;
      }
    }
 @ApiModel(description = "Child holds the descriptive information of currencies translated into various languages supported by the application.")
 @Entity
 @Table(name = "child")
 @Cache(usage = CacheConparentStrategy.NONSTRICT_READ_WRITE)
 @Document(indexName = "child")
 public class Child extends AbstractEntity {

   private static final long serialVersionUID = 6419585975683709213L;

   /**
    * Identifier of the descriptive information.
    */
   @Id
   @GeneratedValue(generator = "system-uuid")
   @GenericGenerator(name = "system-uuid", strategy = "uuid2")
   @Column(name = "id", columnDefinition = "CHAR", length = 36, nullable = false)
   private String id;

   /**
    * Name of the parent.
    */
   @NotNull
   @Size(min = 3, max = 120)
   @Column(name = "entity_name", columnDefinition = "VARCHAR", length = 120, nullable = false)
   private String entityName;

   /**
    * Brief description about the parent.
    */
   @Size(max = 256)
   @Column(name = "entity_desc", columnDefinition = "VARCHAR", length = 256, nullable = true)
   private String entityDesc;

   @ManyToOne(fetch = FetchType.EAGER)
   @JsonIgnoreProperties("childs")
   private Parent parent;

   @ManyToOne(fetch = FetchType.EAGER)
   private Language language;

   /**
    * Callback method that is triggered before persisting the descriptive information of the parent where default
    * values are set for mandatory attributes and values are massaged without compromising on data integrity.
    */
   @PrePersist
   public void setDefaultValues() {
     this.entityName = StringUtils.capitalize(StringUtils.trim(this.entityName));
     this.entityDesc = StringUtils.trim(this.entityDesc);
   }

   /**
    * @return the id
    */
   public String getId() {
     return id;
   }

   /**
    * @param id the id to set
    */
   public void setId(String id) {
     this.id = id;
   }

   /**
    *
    * @return
    */
   public String getEntityName() {
     return entityName;
   }

   /**
    *
    * @param entityName
    * @return
    */
   public Child entityName(String entityName) {
     this.entityName = entityName;
     return this;
   }

   /**
    *
    * @param entityName
    */
   public void setEntityName(String entityName) {
     this.entityName = entityName;
   }

   /**
    *
    * @return
    */
   public String getEntityDesc() {
     return entityDesc;
   }

   /**
    *
    * @param entityDesc
    * @return
    */
   public Child entityDesc(String entityDesc) {
     this.entityDesc = entityDesc;
     return this;
   }

   /**
    *
    * @param entityDesc
    */
   public void setEntityDesc(String entityDesc) {
     this.entityDesc = entityDesc;
   }

   /**
    *
    * @return
    */
   public Parent getParent() {
     return parent;
   }

   /**
    *
    * @param parent
    * @return
    */
   public Child parent(Parent parent) {
     this.parent = parent;
     return this;
   }

   /**
    *
    * @param parent
    */
   public void setParent(Parent parent) {
     this.parent = parent;
   }

   public Language getLanguage() {
     return language;
   }

   public Child language(Language language) {
     this.language = language;
     return this;
   }

   public void setLanguage(Language language) {
     this.language = language;
   }

   @Override
   public boolean equals(Object o) {
     if (this == o) {
       return true;
     }
     if (o == null || getClass() != o.getClass()) {
       return false;
     }
     Child child = (Child) o;
     if (child.getId() == null || getId() == null) {
       return false;
     }
     return Objects.equals(getId(), child.getId());
   }

   @Override
   public int hashCode() {
     return Objects.hashCode(getId());
   }

   @Override
   public String toString() {
     return "Child{"
       + "id=" + getId()
       + ", entityName='" + getEntityName() + "'"
       + ", entityDesc='" + getEntityDesc() + "'"
       + "}";
   }
 }



@ApiModel(description = "Parent class holds the primary definition of a parent such as parent code, parent symbol etc.")
@Entity
@Table(name = "parent")
@Cache(usage = CacheConparentStrategy.NONSTRICT_READ_WRITE)
@Document(indexName = "parent")
public class Parent extends AbstractEffectiveEntity {

  private static final long serialVersionUID = 5671242791959882244L;

  /**
   * Identifier of the parent.
   */
  @Id
  @GeneratedValue(generator = "system-uuid")
  @GenericGenerator(name = "system-uuid", strategy = "uuid2")
  @Column(name = "id", columnDefinition = "CHAR", length = 36, nullable = false)
  private String id;

  /**
   * Code assigned to the parent.
   */
  @NotNull
  @Size(min = 2, max = 5)
  @Column(name = "parent_code", columnDefinition = "CHAR", length = 5, nullable = false, updatable = false)
  private String parentCode;

  /**
   * Symbol associated with the parent.
   */
  @NotNull
  @Size(min = 2, max = 10)
  @Column(name = "parent_symbol", columnDefinition = "VARCHAR", length = 10, nullable = false, updatable = false)
  private String parentSymbol;

  /**
   * Flag to denote whether parent is installed in the product suite to support converting it to other currencies.
   */
  @Column(name = "installed_flag", columnDefinition = "CHAR", length = 1, nullable = false)
  private String installedFlag;

  /**
   * Bi-directional OneToMany is not the best and most efficient way to model a one to many relationship. But in this
   * case we prefer to keep a collection of descriptive information (children) in Parent (parent) to retrieve the
   * descriptive information via Parent, since the count of descriptive information shall be less (depending on the
   * number of languages supported in the application for translation). Limitations of this are (1) inability to limit
   * the number of descriptive information (Child) loaded and thus no support for pagination, (2) inability to sort
   * descriptive information since @OrderColumn annotation can be expensive.
   */
  @OneToMany(mappedBy = "parent")

  @Cache(usage = CacheConparentStrategy.NONSTRICT_READ_WRITE)
  private Set<Child> childs = new HashSet<>();

  /**
   * Callback method that is triggered before persisting the primary information of the parent where default values
   * are set for mandatory attributes and values of key attributes are massaged without compromising on data integrity.
   */
  @PrePersist
  public void setDefaultValues() {
    this.parentCode = StringUtils.upperCase(StringUtils.trim(this.parentCode));
    this.parentSymbol = StringUtils.trim(this.parentSymbol);
    this.installedFlag = StringUtils.upperCase(StringUtils.trim(this.installedFlag));
    if (StringUtils.isBlank(this.installedFlag)) {
      this.installedFlag = "N";
    }
  }

  /**
   * Returns the identifier of the parent.
   *
   * @return the parent identifier.
   */
  public String getId() {
    return id;
  }

  /**
   * Sets the identifier of the parent.
   *
   * @param id the identifier to be set for the parent.
   */
  public void setId(String id) {
    this.id = id;
  }

  /**
   * Returns the code associated with the parent.
   *
   * @return the parentCode
   */
  public String getParentCode() {
    return parentCode;
  }

  /**
   * Sets the code associated with the parent.
   *
   * @param parentCode the parentCode to set
   */
  public void setParentCode(String parentCode) {
    this.parentCode = parentCode;
  }

  /**
   * Sets the code of the parent in the Parent object.
   *
   * @param parentCode
   * @return parent the Parent object with parentCode set.
   */
  public Parent parentCode(String parentCode) {
    this.parentCode = parentCode;
    return this;
  }

  /**
   * Returns the symbol associated with the parent.
   *
   * @return the parentSymbol
   */
  public String getParentSymbol() {
    return parentSymbol;
  }

  /**
   * Sets the symbol associated with the parent.
   *
   * @param parentSymbol the parentSymbol to set
   */
  public void setParentSymbol(String parentSymbol) {
    this.parentSymbol = parentSymbol;
  }

  /**
   * Sets the symbol of the parent in the Parent object.
   *
   * @param parentSymbol
   * @return parent the Parent object with parentSymbol set.
   */
  public Parent parentSymbol(String parentSymbol) {
    this.parentSymbol = parentSymbol;
    return this;
  }

  /**
   * Return true if the parent is marked as installed in the product suite, otherwise false.
   *
   * @return the installedFlag
   */
  public String getInstalledFlag() {
    return installedFlag;
  }

  /**
   * Setter method to specify whether the parent is marked as installed in the product suite or not.
   *
   * @param installedFlag the installedFlag to set
   */
  public void setInstalledFlag(String installedFlag) {
    this.installedFlag = installedFlag;
  }

  /**
   * Sets the flag to denote whether the parent is installed in the product suite or note in the Parent object.
   *
   * @param installedFlag
   * @return the Parent object with installedFlag set.
   */
  public Parent installedFlag(String installedFlag) {
    this.installedFlag = installedFlag;
    return this;
  }

  /**
   *
   * @return
   */
  public Set<Child> getChilds() {
    return childs;
  }

  /**
   *
   * @param childs
   * @return
   */
  public Parent childs(Set<Child> childs) {
    this.childs = childs;
    return this;
  }

  /**
   *
   * @param child
   * @return
   */
  public Parent addChild(Child child) {
    this.childs.add(child);
    child.setParent(this);
    return this;
  }

  /**
   *
   * @param child
   * @return
   */
  public Parent removeChild(Child child) {
    this.childs.remove(child);
    child.setParent(null);
    return this;
  }

  /**
   *
   * @param childs
   */
  public void setChilds(Set<Child> childs) {
    this.childs = childs;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    Parent parent = (Parent) o;
    if (parent.getId() == null || getId() == null) {
      return false;
    }
    return Objects.equals(getId(), parent.getId());
  }

  @Override
  public int hashCode() {
    return Objects.hashCode(getId());
  }

  @Override
  public String toString() {
    return "Parent{" + "id=" + getId() + ", parentCode='" + getParentCode() + "'" + ", parentSymbol='"
      + getParentSymbol() + "'" + ", installedFlag='" + getInstalledFlag() + "'" + "}";
  }

}

共有1个答案

柯子琪
2023-03-14

您正在寻找的可能是将映射目标类型传递给自定义映射器或按ID查找实体的示例。

您可以拥有一个抽象映射器,在该映射器中可以插入存储库并执行实体查找。或者您甚至可以将存储库作为@context参数传递。

让我们假设您有parentrepository,其中有findbyid(String id)

@Component
public class ChildMapperImpl implements ChildMapper {

    @Autowired
    private ParentRepository parentRepository;

    @Autowired
    private ChildFactory childFactory;


    @Override
    public Child toEntity(ChildDTO childDTO) {
        Child child = childFactory.create(childDTO);

        child.setParent(parentRepository.findById(childDTO.getParentId());
    }
}

例如,为了获取子级以执行更新,可以使用如下内容:

public class ChildFactory {

    protected final ChildRepository childRepository;

    public ChildFactory(ChildRepository childRepository) {
        this.childRepository = childRepository;
    }

    @ObjectFactory
    public Child create(ChildDTO childDTO) {
        Child child = childRepository.findById(childDTO.getId());
        return child == null ? new Child() : child;
    }
}
 类似资料:
  • 我不熟悉Mapstruct,在特定用例中遇到问题 因此,如果我的来源属性hotmail.com我的目标属性应该收到“个人”,如果我的来源facebook.com我的目标应该收到“公司”。 我想用表达法,但没法绕过它。我该怎么做?

  • 我想映射2个模型,其中每个模型都有几乎相同的枚举。让我展示: 第一个模型有枚举: 第二个模型具有枚举: 我有这样的自定义映射方法: 然后我用: 但是你可以得到: 我还创建了枚举映射器,如: 但我不需要单独设置,只希望枚举字段映射到内部映射中。简单地说,当我做枚举时,也应该映射。 谢谢 p、 对不起我的英语,希望我的问题有意义:)

  • 是否可能在MapStruct中使用不同的映射器?我有这个映射器 是否可以将此实现更改为MapStruct?

  • 我在Kotlin-vertx项目中配置了Hibernate,我设法设置了所有内容,但当我运行HQL查询时,它会输出: 提前谢了。

  • 按照第二个链接中包含的示例,我已经测试了: 但我没有实现使用。

  • 我正在使用Hibernate和JPA注释来映射我的类。当hibernate尝试映射这个类时,我遇到了一个问题 我的Social alStat类是: 我得到了这个错误: 我猜发生这种情况是因为我试图映射到一个基本类,但@ElementCollection注释不应该解决这个问题吗? 我的item类如下所示: