1
resposta

[Dúvida] Relacionamento entre tabelas me devolvendo null

Opa turma, beleza? Então...quando insiro o JSON no insominia pra dar um post ele me retorna um status 201 CREATED mas alguns campos me retorna nulo, e são justamente os campos de relacionamento entre tabelas.

Aqui é minha inserção:

{
  "title": "A Revolução dos Bichos",
  "isbn": "9780451526342",
  "yearPublication": 1945,
  "cover": "https://carrefourbr.vtexassets.com/arquivos/ids/14566021/Kit-1984---A-Revolucao-dos-Bichos-George-Orwell-Capa-Comum.jpg?v=637510501552670000",
  "description": "A Revolução dos Bichos é um livro escrito por George Orwell, publicado pela primeira vez em 1945. Situado em uma fazenda, o romance utiliza animais antropomorfizados para retratar uma crítica ao totalitarismo e ao abuso de poder.",
  "pages": 150,
  "author": {
    "name": "George Orwell"
  },
  "publishingCompany": {
    "name": "Editora Globo"
  },
  "gender": {
    "name": "Ficção"
  }
}

E aqui meu retorno:

{
    "id": 452,
    "title": "A Revolução dos Bichos",
    "author": null,
    "isbn": "9780451526342",
    "yearPublication": 1945,
    "publishingCompany": null,
    "cover": "https://carrefourbr.vtexassets.com/arquivos/ids/14566021/Kit-1984---A-Revolucao-dos-Bichos-George-Orwell-Capa-Comum.jpg?v=637510501552670000",
    "gender": null,
    "description": "A Revolução dos Bichos é um livro escrito por George Orwell, publicado pela primeira vez em 1945. Situado em uma fazenda, o romance utiliza animais antropomorfizados para retratar uma crítica ao totalitarismo e ao abuso de poder.",
    "pages": 150
}

Irei deixar aqui também meu DTO, meu Model e meu Controller.

DTO:

public record BooksRecordDTO(
    @NotBlank
    String title,
    @NotBlank
    String isbn,
    @NotNull
    Integer yearPublication,
    @NotBlank
    String cover,
    @NotBlank
    String description,
    @NotNull
    Integer pages,
    @JsonProperty("author")
    @Valid
    AuthorRecordDTO author,
    @JsonProperty("publishing_company")
    @Valid
    PublishingCompanyRecordDTO publishingCompany,
    @JsonProperty("gender")
    @Valid
    GenderRecordDTO gender
) {
}

Model:

@Entity
@Table(name = "TB_BOOKS")
public class BooksModels extends RepresentationModel<BooksModels> implements Serializable {
  private static final long serialVersionUID = 1L;

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;
  private String title;
  @ManyToOne
  @JoinColumn(name = "author_id")
  private AuthorModels author;
  private String isbn;
  private Integer yearPublication;
  @ManyToOne
  @JoinColumn(name = "publishing_company_id")
  private PublishingCompanyModels publishingCompany;
  private String cover;
  @ManyToOne
  @JoinColumn(name = "gender_id")
  private GenderModels gender;
  private String description;
  private Integer pages;

  public Long getId() {
    return id;
  }

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

  public String getTitle() {
    return title;
  }

  public void setTitle(String title) {
    this.title = title;
  }

  public AuthorModels getAuthor() {
    return author;
  }

  public void setAuthor(AuthorModels author) {
    this.author = author;
  }

  public String getIsbn() {
    return isbn;
  }

  public void setIsbn(String isbn) {
    this.isbn = isbn;
  }

  public Integer getYearPublication() {
    return yearPublication;
  }

  public void setYearPublication(Integer yearPublication) {
    this.yearPublication = yearPublication;
  }

  public PublishingCompanyModels getPublishingCompany() {
    return publishingCompany;
  }

  public void setPublishingCompany(PublishingCompanyModels publishingCompany) {
    this.publishingCompany = publishingCompany;
  }

  public String getCover() {
    return cover;
  }

  public void setCover(String cover) {
    this.cover = cover;
  }

  public GenderModels getGender() {
    return gender;
  }

  public void setGender(GenderModels gender) {
    this.gender = gender;
  }

  public String getDescription() {
    return description;
  }

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

  public Integer getPages() {
    return pages;
  }

  public void setPages(Integer pages) {
    this.pages = pages;
  }
}

Controller:

@RestController
public class BooksController {
  @Autowired
  BooksRepository booksRepository;
  @PostMapping("/api/v1/books")
  public ResponseEntity<BooksModels> saveBooks(
          @RequestBody @Valid BooksRecordDTO booksRecordDTO) {

    var booksModels = new BooksModels();
    BeanUtils.copyProperties(booksRecordDTO, booksModels);

    return ResponseEntity.status(HttpStatus.CREATED).body(booksRepository.save(booksModels));
  }
}
1 resposta

Olá Magno!

O problema que você está enfrentando é que os campos de relacionamento entre tabelas (author, publishingCompany e gender) estão retornando como nulos no momento da inserção dos dados. Isso acontece porque você está usando os objetos DTO (Data Transfer Objects) para realizar o mapeamento dos dados recebidos no JSON para o objeto de modelo (BooksModels), mas não está configurando os objetos relacionados corretamente.

Para resolver esse problema, você precisa garantir que os objetos relacionados (AuthorModels, PublishingCompanyModels e GenderModels) estejam devidamente configurados e associados ao objeto BooksModels antes de salvá-lo no banco de dados.

Aqui estão algumas sugestões para corrigir o problema:

  1. Configurar os objetos relacionados no Controller: No método saveBooks() do Controller, você precisa configurar corretamente os objetos relacionados (AuthorModels, PublishingCompanyModels e GenderModels) antes de copiar as propriedades do DTO para o objeto BooksModels. Para fazer isso, você pode usar métodos específicos para buscar ou criar esses objetos no banco de dados, com base nos dados fornecidos no JSON.

  2. Ajustar o DTO para receber IDs dos objetos relacionados: No DTO, em vez de receber os objetos relacionados completos (AuthorRecordDTO, PublishingCompanyRecordDTO e GenderRecordDTO), você pode ajustá-lo para receber apenas os IDs desses objetos. Em seguida, no Controller, você pode buscar os objetos no banco de dados com base nesses IDs e configurá-los corretamente no objeto BooksModels.

Por exemplo, o DTO pode ser ajustado assim:

public record BooksRecordDTO(
    // ... outras propriedades ...
    @NotNull
    Long authorId,
    @NotNull
    Long publishingCompanyId,
    @NotNull
    Long genderId
) {
}

E no método saveBooks() do Controller, você pode buscar os objetos relacionados a partir dos IDs:

// ...

@Autowired
AuthorRepository authorRepository;

@Autowired
PublishingCompanyRepository publishingCompanyRepository;

@Autowired
GenderRepository genderRepository;

@PostMapping("/api/v1/books")
public ResponseEntity<BooksModels> saveBooks(@RequestBody @Valid BooksRecordDTO booksRecordDTO) {
    var booksModels = new BooksModels();
    BeanUtils.copyProperties(booksRecordDTO, booksModels);

    // Buscar os objetos relacionados com base nos IDs recebidos no DTO
    AuthorModels author = authorRepository.findById(booksRecordDTO.getAuthorId()).orElse(null);
    PublishingCompanyModels publishingCompany = publishingCompanyRepository.findById(booksRecordDTO.getPublishingCompanyId()).orElse(null);
    GenderModels gender = genderRepository.findById(booksRecordDTO.getGenderId()).orElse(null);

    // Configurar os objetos relacionados no objeto BooksModels
    booksModels.setAuthor(author);
    booksModels.setPublishingCompany(publishingCompany);
    booksModels.setGender(gender);

    return ResponseEntity.status(HttpStatus.CREATED).body(booksRepository.save(booksModels));
}

// ...

Com essas alterações, o Controller irá buscar corretamente os objetos relacionados no banco de dados com base nos IDs fornecidos no JSON e configurá-los no objeto BooksModels antes de salvá-lo no banco de dados. Isso deve resolver o problema e fazer com que os campos de relacionamento não sejam mais nulos após a inserção.

Espero que isso ajude! Se você tiver mais perguntas ou precisar de mais esclarecimentos, fique à vontade para perguntar!