Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why is the database looping when calling the GET method?

The main entity:
it uses a one-to-one relationship to the "animal_passport" table. Everything is done according to the textbook and should work well. But for some reason, both tables refer to each other when calling the get method.

package com.testapp.model;
import javax.persistence.*;
@Entity
@Table(name = "animal")
public class Animal {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "animal_id", nullable = false, updatable = false)
private long id;
@Column(name = "animal_value")
private String animal_value;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "pass_id")
private PassportAnimal passportAnimal;

public Animal(String animal_value, PassportAnimal passportAnimal) {
    this.animal_value = animal_value;
    this.passportAnimal = passportAnimal;
}
public Animal() {
}
public long getId() {
    return id;
}
public void setId(long id) {
    this.id = id;
}
public String getAnimal_value() {
    return animal_value;
}
public void setAnimal_value(String animal_value) {
    this.animal_value = animal_value;
}
public PassportAnimal getPassportAnimal() {
    return passportAnimal;
}
public void setPassportAnimal(PassportAnimal passportAnimal) {
    this.passportAnimal = passportAnimal;
}
}

Dependent entity:

package com.testapp.model;
import javax.persistence.*;
@Entity
@Table(name = "pass_anim")
public class PassportAnimal {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "pass_id", nullable = false,updatable = false)
private long id;
@Column(name = "value_pass")
private String value;
@OneToOne(mappedBy = "passportAnimal")
private Animal animal;

public PassportAnimal(String value, Animal animal) {
    this.value = value;
    this.animal = animal;
}
public PassportAnimal() {
}
public long getId() {
    return id;
}
public void setId(long id) {
    this.id = id;
}
public String getValue() {
    return value;
}
public void setValue(String value) {
    this.value = value;
}
public Animal getAnimal() {
    return animal;
}
public void setAnimal(Animal animal) {
    this.animal = animal;
}
}

Controller the animal entity:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

package com.testapp.controller;
import com.testapp.model.Animal;
import com.testapp.repository.AnimalRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@CrossOrigin(origins = "http://localhost:8080")
@RestController
@RequestMapping(path = "/api")
public class AnimalController {
@Autowired
AnimalRepository animalRepository;
@GetMapping("/animal")
public ResponseEntity<List<Animal>> getAllAnimal(@RequestParam(required = false) String value) 
{
    try {
        List<Animal> animals = new ArrayList<>();
        if (value == null) {
            animalRepository.findAll().forEach(animals::add);
        }
        if (animals.isEmpty()) {
            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
        }
        return new ResponseEntity<>(animals, HttpStatus.OK);
    } catch (Exception e) {
        return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}
@GetMapping("/animal/{id}")
public ResponseEntity<Animal> getAnimalById(@PathVariable("id") long id) {
    Optional<Animal> animalOptional = animalRepository.findById(id);
    if (animalOptional.isPresent()) {
        return new ResponseEntity<>(animalOptional.get(), HttpStatus.OK);
    } else {
        return new ResponseEntity<>(HttpStatus.NOT_FOUND);
    }
}
@PostMapping("/animal")
public ResponseEntity<Animal> createAnimal(@RequestBody Animal animal) {
    try {
        Animal _animal = animalRepository.save(new 
Animal(animal.getAnimal_value(),animal.getPassportAnimal()));
        return new ResponseEntity<>(_animal, HttpStatus.CREATED);
    } catch (Exception e) {
        e.printStackTrace();
        return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}
@PutMapping("/animal/{id}")
public ResponseEntity<Animal> updateAnimal(@PathVariable("id") long id, @RequestBody Animal 
animal) {
    try {
        Optional<Animal> animalOptional = animalRepository.findById(id);

        if (animalOptional.isPresent()) {
            Animal _animal = animalOptional.get();
            _animal.setAnimal_value(animal.getAnimal_value());
            _animal.setPassportAnimal(animal.getPassportAnimal());
            return new ResponseEntity<>(animalRepository.save(_animal), HttpStatus.OK);
        } else {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
    } catch (Exception e) {
        e.printStackTrace();
        return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}
@DeleteMapping("/animal/{id}")
public ResponseEntity<HttpStatus> deleteAnimal(@PathVariable("id") long id) {
    try {
        animalRepository.deleteById(id);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    } catch (Exception e) {
        return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
    }
}
@DeleteMapping("/animal")
public ResponseEntity<HttpStatus> deleteAllAnimals() {
    try {
        animalRepository.deleteAll();
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    } catch (Exception e) {
        return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
    }
}
}

When calling the GET method, the animal and its passport should be output. But an infinite json is output. Inside the passport, the animal is displayed again and again his passport.

>Solution :

You have to break the loop with Jackson annotations.

One one side you can set @JsonManagedReference and this will be serialized and on the other you set @JsonBackReference and this one will be ignored.

Please find a good explanation here: https://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading