'Multiple list of Data comming in API when using ManyToOne Relationship

CarMake.java

@Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor
@Entity
public class CarMake {
    @SequenceGenerator(
            name = "car_make_sequence",
            sequenceName = "car_make_sequence",
            allocationSize = 1
    )
    @Id
    @GeneratedValue(
            strategy = GenerationType.SEQUENCE,
            generator = "car_make_sequence"
    )
    private Long id;
    private String name;
    @CreationTimestamp
    private LocalDateTime createdAt;
    @UpdateTimestamp
    private LocalDateTime updatedAt;
    @OneToMany(mappedBy = "make", cascade = CascadeType.ALL)
    private List<CarModel> model;
}

CarModel.java

@Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor
@Entity
public class CarModel {
    @SequenceGenerator(
            name = "car_model_sequence",
            sequenceName = "car_model_sequence",
            allocationSize = 1
    )
    @Id
    @GeneratedValue(
            strategy = GenerationType.SEQUENCE,
            generator = "car_model_sequence"
    )
    private Long id;
    private String name;
    private Integer beginDate;
    private Integer endDate;
    @CreationTimestamp
    private LocalDateTime createdAt;
    @UpdateTimestamp
    private LocalDateTime updatedAt;
    @ManyToOne(fetch = FetchType.EAGER)
    CarMake make;
    @OneToMany(mappedBy = "model", cascade = CascadeType.ALL)
    private List<CarVariant> variants;

}

CarVariant.java

@Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor
@Entity
public class CarVariant {
    @SequenceGenerator(
            name = "car_variant_sequence",
            sequenceName = "car_variant_sequence",
            allocationSize = 1
    )
    @Id
    @GeneratedValue(
            strategy = GenerationType.SEQUENCE,
            generator = "car_variant_sequence"
    )
    private Long id;
    @Column(nullable = false)
    private String name;
    @CreationTimestamp
    private LocalDateTime createdAt;
    @UpdateTimestamp
    private LocalDateTime updatedAt;
    @ManyToOne(fetch = FetchType.LAZY)
    CarModel model;
}

If i am using repository i am getting loop of data which is not present even in database

@GetMapping("api/car/model/{id}")
    @ResponseBody
    public Iterable<CarMake> showCarModelsByMakeId(@PathVariable Long id){
        return carMakeRepository.findAll();
    }

Bellow is the response of API

[{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983","updatedAt":"2022-05-06T17:07:48.40903","model":[{"id":1,"name":"hello","beginDate":1,"endDate":3,"createdAt":"2022-05-06T17:07:59.440783","updatedAt":"2022-05-06T17:07:59.440826","make":{"id":1,"name":"hello","createdAt":"2022-05-06T17:07:48.408983",

I beleive i should get only one instance of data as only one row is present in table. what is the reason i am getting so much data, did i created onetomany relationship correctly?, how i can achieve it

Database data enter image description here



Solution 1:[1]

This is a famous bidirectional issue. In few words, your CarMake entity references CarModel, which in its turn, references back to CarMake, what causes an infinitive loop. Try to put @JsonIgnore annotation on CarMake make in your CarModel entity and repeat the test.

PS: better to not to return entity objects from your rest controller, use either DTO mapping, or projections

PPS: don't use @EqualsAndHashCode on @Entity classes

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 meridbt