简体   繁体   English

如何将JSON主体中的数组映射到POJO?

[英]How to map array in the JSON body to a POJO?

I'm implementing many-to-many relationship using hibernate as JPA and spring-boot. 我正在使用Hibernate作为JPA和spring-boot来实现多对多关系。 When I do a post request from the POSTMAN, I get the following error: 当我从POSTMAN发出发帖请求时,出现以下错误:

Failed to convert from type [java.net.URI] to type [com.domain.Datasource]

There is a many to many relationship between Metric and Datasource . MetricDatasource之间存在多对多关系。

JSON body JSON正文

{
    "companyId" : "fake_company_id",
    "name" : "test_name",
    "description" :"test Description",
    "datasources" :  ["fdaea7d4162bd2c3f3db5ba059638123"]
}

Metric.java Metric.java

@Entity
public class Metric implements Persistable<Long> {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(nullable = false)
@RestResource(exported = false)
private Long id;

@Column(nullable = false, unique = true)
private String publicId;
@Column(nullable = false)
private String name;
private MetricType type;

@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "metric_datasource", joinColumns = @JoinColumn(name = "metric_id", referencedColumnName = "id"), inverseJoinColumns =  @JoinColumn(name = "datasource_id", referencedColumnName = "id"))
private Set<Datasource> datasources ;
private String definition;
private long dateCreated;
private String description;
private String companyId;

protected Metric() {
    this.dateCreated = new Date().getTime();
}

public Metric(String name, String publicId, String definition) {
    super();
    this.name = name;
    this.publicId = publicId;
    this.definition = definition;
}

@JsonIgnore
@Override
public boolean isNew() {
    return null == getId();
}

@PrePersist
public void generatePublicId() {
    publicId = PublicIdGenerator.generate(32);
}

@Override
public Long getId() {
    return id;
}

public String getPublicId() {
    return publicId;
}

public void setPublicId(String publicId) {
    this.publicId = publicId;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getDefinition() {
    return definition;
}

public void setDefinition(String definition) {
    this.definition = definition;
}

public void setDateCreated(long dateCreated) {
    this.dateCreated = dateCreated;
}

public long getDateCreated(){
    return this.dateCreated;
}

public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}

public Set<Datasource> getDatasources() {
    if (datasources != null) {
        return datasources;
    } else {
        return Collections.emptySet();
    }
}

public void setDatasources(Set<Datasource> datasources) {
    if (datasources != null) {
        this.datasources = datasources;
    } else {
        this.datasources = Collections.emptySet();
    }
}

public void setId(Long id) {
    this.id = id;
}

public String getCompanyId() {
    return companyId;
}

public void setCompanyId(String companyId) {
    this.companyId = companyId;
}

public MetricType getType() {
    return type;
}

public void setType(MetricType type) {
    this.type = type;
}

public void update(Metric metric) {
    if (metric.getName() != null) {
        setName(metric.getName());
    }

    if (metric.getDescription() != null) {
        setDescription(metric.getDescription());
    }
    if (metric.getDefinition() != null) {
        setDefinition(metric.getDefinition());
    }
}

Datasource.java Datasource.java

@Entity
public class Datasource implements Persistable<Long> {

@Column(nullable = false, unique = true)
private String publicId;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(nullable = false)
@RestResource(exported = false)
private Long id;

@ManyToMany(mappedBy = "datasources")
private Set<Metric> metrics;

public Datasource() {
    this(null);
}

public Datasource(String publicId) {
    this.publicId = publicId;
}

public String getPublicId() {
    return publicId;
}

public void setPublicId(String publicId) {
    this.publicId = publicId;
}

@Override
public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

@Override
public boolean isNew() {
    return null == getId();
}

public Set<Metric> getMetrics() {
    return metrics;
}

public void setMetrics(Set<Metric> metrics) {
    this.metrics = metrics;
}

Currently the relationship between Metric and Datasource is set properly , ie I have three tables metric , datasource and metric_datasource created in the database. 当前,度量标准和数据源之间的关系已正确设置,即我在数据库中创建了三个表metricdatasourcemetric_datasource But I'm not sure how can I save the value using the give JSON body. 但是我不确定如何使用Give JSON正文保存值。 Please help. 请帮忙。

First, make sure that method in your REST-controller can consume "application/json", has a proper @RequestBody annotation in it's arguments. 首先,确保REST控制器中的方法可以使用“ application / json”,并且在其参数中具有正确的@RequestBody批注。
Second, I think sending a full-scale domain-like objects from client is not correct. 其次,我认为从客户端发送全面的类域对象是不正确的。 You should implement DTO for class Metric that would fully match the JSON you've provided. 您应该为Metric类实现与您提供的JSON完全匹配的DTO And the datasources property should be List<String> containing the actual datasources' ids in that case. 并且在这种情况下, datasources属性应为List<String>其中包含实际数据源的ID。

Then you should implement a method in your that would convert DTO to domain object (where you can fetch DataSource objects for each datasource id stored in DTO) to persist it then. 然后,您应该在自己的方法中实现将DTO转换为域对象的方法(您可以在其中获取DTO中存储的每个数据源ID的DataSource对象)以将其持久化。

// assuming that you already implemented any JpaRepository<Metric> interface
@Autowired
private MetricRepository metricRepo;

@Autowired
private DataSourceRepository dataSourceRepo;

public Metric saveMetricDTO(MetricDTO dto) {
  Metric metric = metricRepo.findByName(dto.getName()); // or fetch by any other suitable property
  // assign all props from DTO to metric: metric.setSmth(dto.getSmth())
  // ...
  List<DataSource> dsList = dto.getDataSourceIds().stream()
    .map(dataSourceRepo::findOne)
    .collect(Collectors.toList())
  metric.setDataSources(dsList);
  metricRepo.save(metric); // finally persist object
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM