Uma outra forma de resolver sem colocar DTO’s no meio é usar as anotações @JsonManagedReference e @JsonBackReference. Elas servem exatamente para este tipo de problema e funcionam da seguinte forma:
-
JsonManagedReference é a referencia gerenciada do objeto, ou seja, vai seguir o fluxo de serialização normalmente.
-
JsonBackReference desacopla o objeto do fluxo de serialização e cria-se uma referência do mesmo no momento da serialização.
Veja no seu próprio exemplo:
@OneToOne
@JoinColumn(name = "cliente", nullable = false)
@JsonManagedReference
private Cliente cliente;
@OneToOne(mappedBy = "cliente")
@JoinColumn(name = "registro", nullable = false) // se vc tem a coluna registro no seu modelo de cliente, não precisa do mappedBy. Se vc não tem essa coluna, mas o relacionamento é necessário, vc não precisa do JoinColumn
@JsonBackReference
private DetalhesDoCliente registro;
Logo, quando vc buscar a entidade DetalhesDoCliente, o atributo Cliente - marcado como uma referência gerenciada - entrará no fluxo de serialização normalmente, porém, o atributo DetalhesDoCliente já na classe Cliente, está anotado como uma referência de volta, logo, sua serialização será ignorada pelo Jersey. Isso resolve de forma mais amigável e correta o problema de recursividade infinita.
Imagine se vc tiver 100 classes com relacionamento semelhante. Terá que criar 100 DTO’s? Particularmente, não gosto desta solução.
Resumindo de forma grosseira:
- JsonManagedReference indica que o atributo deve ser serializado
- JsonBackReference cria uma dependência lógica do atributo, mas não o serializa.
Ah, os recursos são do pacote com.fasterxml.jackson.annotation