在@ManyToOne关系中简化JSON序列化

时间:2017-11-28 11:25:57

标签: hibernate jpa jackson spring-data-jpa

我对使用Spring JPA进行ORM映射有疑问。

考虑一个简单的类Person:

/tmp/ccBH8KfT.o: In function `boost::archive::detail::common_iarchive<boost::archive::binary_iarchive>::vload(boost::archive::class_name_type&)':
main.cpp:(.text._ZN5boost7archive6detail15common_iarchiveINS0_15binary_iarchiveEE5vloadERNS0_15class_name_typeE[_ZN5boost7archive6detail15common_iarchiveINS0_15binary_iarchiveEE5vloadERNS0_15class_name_typeE]+0x1): undefined reference to `boost::archive::basic_binary_iarchive<boost::archive::binary_iarchive>::load_override(boost::archive::class_name_type&)'
/tmp/ccBH8KfT.o: In function `void boost::serialization::throw_exception<boost::archive::archive_exception>(boost::archive::archive_exception const&)':
main.cpp:(.text._ZN5boost13serialization15throw_exceptionINS_7archive17archive_exceptionEEEvRKT_[_ZN5boost13serialization15throw_exceptionINS_7archive17archive_exceptionEEEvRKT_]+0x1a): undefined reference to `boost::archive::archive_exception::archive_exception(boost::archive::archive_exception const&)'
/tmp/ccBH8KfT.o: In function `boost::exception_detail::error_info_injector<boost::archive::archive_exception>::error_info_injector(boost::exception_detail::error_info_injector<boost::archive::archive_exception> const&)':
main.cpp:(.text._ZN5boost16exception_detail19error_info_injectorINS_7archive17archive_exceptionEEC2ERKS4_[_ZN5boost16exception_detail19error_info_injectorINS_7archive17archive_exceptionEEC5ERKS4_]+0x18): undefined reference to `boost::archive::archive_exception::archive_exception(boost::archive::archive_exception const&)'
/tmp/ccBH8KfT.o: In function `boost::exception_detail::error_info_injector<boost::archive::archive_exception>::error_info_injector(boost::exception_detail::error_info_injector<boost::archive::archive_exception> const&)':
main.cpp:(.text._ZN5boost16exception_detail19error_info_injectorINS_7archive17archive_exceptionEEC1ERKS4_[_ZN5boost16exception_detail19error_info_injectorINS_7archive17archive_exceptionEEC5ERKS4_]+0x19): undefined reference to `boost::archive::archive_exception::archive_exception(boost::archive::archive_exception const&)'
/tmp/ccBH8KfT.o: In function `boost::exception_detail::error_info_injector<boost::archive::archive_exception>::error_info_injector(boost::archive::archive_exception const&)':
main.cpp:(.text._ZN5boost16exception_detail19error_info_injectorINS_7archive17archive_exceptionEEC2ERKS3_[_ZN5boost16exception_detail19error_info_injectorINS_7archive17archive_exceptionEEC5ERKS3_]+0xe): undefined reference to `boost::archive::archive_exception::archive_exception(boost::archive::archive_exception const&)'
/tmp/ccBH8KfT.o: In function `boost::exception_detail::error_info_injector<boost::archive::archive_exception>::error_info_injector(boost::archive::archive_exception const&)':
main.cpp:(.text._ZN5boost16exception_detail19error_info_injectorINS_7archive17archive_exceptionEEC1ERKS3_[_ZN5boost16exception_detail19error_info_injectorINS_7archive17archive_exceptionEEC5ERKS3_]+0x14): undefined reference to `boost::archive::archive_exception::archive_exception(boost::archive::archive_exception const&)'

和一个简单的类Car:

@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....

人与Car有一个OneToMany关系。

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

@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": {
    "personId": 200,
    "name": "Jack"
  },
  "typeOfCar": "Ferrari"
}

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

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

如何实现这一目标?

到目前为止,我所尝试的是Car中Person参考的以下注释 @JsonIdentityReference @JsonIdentityInfo ,如下所示:

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

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

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

1 个答案:

答案 0 :(得分:2)

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

  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);
      }
    
    }