Схема OpenAPI для JsonIdentityReference-нормализованных объектов JPA

#spring-boot #spring-data-jpa #jackson #openapi #springdoc

Вопрос:

Используя службы @RestController, CrudRepository и glue@, я предоставляю доступ к некоторым объектам на основе JPA.

User Класс ссылается List<Order> на, в то время Order как ссылки на User .

Чтобы разорвать бесконечные циклы рекурсии Джексона, я заменяю вложенные объекты через @JsonIdentityReference(alwaysAsId=true) . Однако springdoc, похоже, игнорирует это и по-прежнему создает спецификацию OpenAPI, которая указывает Order вместо, например Long (класс id).

Как указать springdoc для сопоставления User.orders List<Long> или (еще лучше) для List<OrderId> ?

 
@RestController
public class UsersController {

    @ApiResponses(value = {
        @ApiResponse(responseCode = "200", description = "successful operation", content = @Content(array = @ArraySchema(schema = @Schema(implementation = User.class))))
    })
    @GetMapping("/")
    public ResponseEntity<Iterable<User>> listUsers() {
        return ResponseEntity.ok(users.findAll());
    }

    // getters and setters omitted

}

@Entity
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class User {

    @Schema(description = "The id of the user", required = true)
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToMany(mappedBy = "order")
    @JsonIdentityReference(alwaysAsId=true)
    private List<Order> orders = Collections.emptyList();

    // getters and setters omitted
}


@Entity
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Order {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id", nullable = false)
    @Schema(required = true)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "user_id")
    @JsonIdentityReference(alwaysAsId=true)
    private User user;

    @OneToMany(mappedBy = "order")
    @JsonIdentityReference(alwaysAsId=true)
    private List<Product> products = Collections.emptyList();

    // getters and setters omitted

}

 

Ответ №1:

Простое решение (нарушает семантику): Добавьте @ArraySchema в определение вот так:

     @OneToMany(mappedBy = "order")
    @JsonIdentityReference(alwaysAsId=true)
    @ArraySchema(schema = @Schema(implementation = Long.class))
    private List<Order> orders = Collections.emptyList();