Boa tarde, Rafael! Tudo joia?
O problema de cadastrar vários livros de uma vez está relacionado a uma particularidade da própria API, pois, quando pesquisamos pelo título, ela retorna vários títulos com aquela nomenclatura. Teste em seu navegador a seguinte URL https://gutendex.com/books/?search=dracula
, você verá que mostrará 3 livros diferentes para um mesmo nome.
Algumas ideias do que você pode fazer para evitar a duplicidade é:
Verificação de duplicidade aprimorada: adicione uma verificação mais robusta para evitar duplicidades, utilizando critérios adicionais além do título, como o autor.
Salvando apenas a primeira ocorrência: utilize uma estrutura de dados para manter o controle dos títulos já processados e salve apenas a primeira ocorrência de cada livro. Para salvar apenas a primeira ocorrência de cada livro, você pode interromper o loop assim que encontrar e salvar o primeiro livro com o título correspondente, usando um break
, por exemplo.
Vou deixar um exemplo de como modifiquei o arquivo LivroService
para essa lógica de salvar apenas a primeira ocorrência:
@Service
public class LivroService {
@Autowired
private LivroRepository livroRepository;
@Autowired
private AutorRepository autorRepository;
private final ConsumoApi consumoApi = new ConsumoApi();
private final ConverterDados conversor = new ConverterDados();
private final String ENDERECO = "http://gutendex.com/books/";
public void saveLivro(String nomeLivro) {
String searchUrl = ENDERECO + "?search=" + nomeLivro.replace(" ", "%20");
boolean livroSalvo = false;
do {
String json = consumoApi.obterDados(searchUrl);
ConsumoApiResponse consumoApiResponse = conversor.obterDados(json, ConsumoApiResponse.class);
if (consumoApiResponse != null && consumoApiResponse.getResults() != null) {
for (Livro livro : consumoApiResponse.getResults()) {
// Se já salvamos um livro, interrompa o loop
if (livroSalvo) {
break;
}
// Verifica se o livro já existe no banco de dados
if (!livroRepository.existsByTitle(livro.getTitle())) {
// Processa e salva os autores do livro
List<Autor> autores = new ArrayList<>();
for (Autor autor : livro.getAuthors()) {
Autor autorExistente = autorRepository.findByNameAndBirthYearAndDeathYear(
autor.getName(), autor.getBirthYear(), autor.getDeathYear()
).orElse(autor);
autores.add(autorExistente);
}
autorRepository.saveAll(autores);
livro.setAuthors(autores);
// Processa e salva os idiomas do livro
List<Idioma> idiomas = new ArrayList<>();
for (Idioma idioma : livro.getIdiomas()) {
Idioma idiomaExistente = new Idioma(idioma.getName());
idiomas.add(idiomaExistente);
}
livro.setIdiomas(idiomas);
// Salva o livro no banco de dados
livroRepository.save(livro);
livroSalvo = true; // Marca que um livro foi salvo
}
}
searchUrl = consumoApiResponse.getNext();
} else {
searchUrl = null;
}
} while (searchUrl != null && !livroSalvo); // Interrompe o loop se um livro foi salvo
}
public List<Livro> listBooks() {
return livroRepository.findAll();
}
@JsonIgnoreProperties(ignoreUnknown = true)
public static class ConsumoApiResponse {
private int count;
private List<Livro> results;
private String next;
// Getters e setters
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public List<Livro> getResults() {
return results;
}
public void setResults(List<Livro> results) {
this.results = results;
}
public String getNext() {
return next;
}
public void setNext(String next) {
this.next = next;
}
}
}
Espero ter ajudado!
Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.