【问题标题】:Simplify JSON serialization in @ManyToOne relationship简化@ManyToOne 关系中的 JSON 序列化
【发布时间】:2017-11-28 11:25:56
【问题描述】:

我有一个关于使用 Spring JPA 进行 ORM 映射的问题。

考虑一个简单的 Person 类:

@Entity
public class Person {

    @Id
    @NotNull
    @Column(unique = true, updatable = false, name = "PERSON_ID")
    private long personId;

    @NotNull
    @Size(min = 1)
    private String name;

    @OneToMany(mappedBy = "person", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private List<Car> cars;

    public Person() {
    } 
    //continue....

还有一个简单的汽车类:

@Entity
public class Car {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "CAR_ID")
    private long carId;

    @NotNull
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "PERSON_ID")
    private Person person;

    @NotNull
    @Size(min = 1)
    private String typeOfCar;

    public Car() {
    } 
    //continue....

Person 与 Car 具有 OneToMany 关系。

回想一下 carId 是自动生成的,当我发布一辆新车时,我不得不指定一个完整的 Person 对象(除了可以为空的汽车列表):

{
  "person": {
    "personId": 200,
    "name": "Jack"
  },
  "typeOfCar": "Ferrari"
}

我希望能够像这样发布汽车对象:

{
  "person": 200,
  "typeOfCar": "Ferrari"
}

因此仅指定 personId(Person 实体的键)。

我想我需要将 Car 中的 Person 引用序列化为它的键而不是整个对象。

如何做到这一点?

到目前为止,我在 Car 中的 Person 引用上尝试了以下注释 @JsonIdentityReference@JsonIdentityInfo,如下所示:

@NotNull
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "PERSON_ID")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "personId")
@JsonIdentityReference(alwaysAsId = true)
private Person person;

但是当我发布简化的 JSON 时,我得到以下 404:

"exception": "org.springframework.http.converter.HttpMessageNotReadableException",
"message": "JSON parse error: Unresolved forward references for: ; nested exception is com.fasterxml.jackson.databind.deser.UnresolvedForwardReference: Unresolved forward references for: \n at [Source: java.io.PushbackInputStream@25614608; line: 5, column: 1]Object id [2] (for myapp.ws.people.entity.Person) at [Source: java.io.PushbackInputStream@25614608; line: 2, column: 13].",

【问题讨论】:

  • 可以使用条件查询还是JPQL?
  • 删除加入列的@not null
  • 不,我不能使用 JPQL。不幸的是,删除 @NotNull 并没有改变任何东西。

标签: hibernate jpa jackson spring-data-jpa


【解决方案1】:

我认为实现它的一种方法是

  1. 创建一个 DTO 类

    class CarDto {
    private long person;
    private String typeOfCar;
    }
    
  2. 那么在您的服务中有 2 个存储库。一个用于人,另一个用于汽车。

    class PersonService {
    
      public void post(CarDto car) {
       Person person = personRepository.findByPersonId(car.getPerson());
       Car newCar = new Car();
       newCar.setPerson(person);
       newCar.setTypeOfCar(car.getTypeOfCar);
       carRepository.save(newCar);
      }
    
    }
    

【讨论】:

  • 我想你问过如何实现你想要拨打的电话。所以这是一种方法。您应该创建一个 DTO 类,然后将其用作控制器中的请求主体,并像答案中提到的那样调用您的服务方法。创建 DTO 类是实现您想要做的事情的非常常用的方法。
  • 是的,这就是答案
猜你喜欢
  • 2020-10-18
  • 2018-04-05
  • 1970-01-01
  • 1970-01-01
  • 2012-05-31
  • 2018-04-29
  • 2013-11-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多