Циклический вызов при OneToOne
Есть Две модели с двусторонним oneToOne но при вызове из репозитория у меня получается циклическое вызывание этих же моделей.
{
"id": 3,
"account": {
"login": "sad",
"password": "asdfsa",
"machine": {
"id": 3,
"account": {
"login": "sad",
"password": "asdfsa",
"machine": {
"id": 3,
"account": {
"login": "sad",
"password": "asdfsa",
"machine": {
"id": 3,
"account": {
"login": "sad",
"password": "asdfsa",
"machine": {
Вот сами модели
@Data
@Entity
@Table(name = "MACHINES")
public class MachineBase implements Serializable {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@OneToOne(fetch = FetchType.LAZY, mappedBy = "machine")
private AccountBase account;
}
и сам аккаунт
@Data
@Entity
@Table(name = "ACCOUNTS")
public class AccountBase implements Serializable {
@Id
@Column(name = "login", nullable = false, unique = true)
private String login;
@Column(name = "password", nullable = false)
private String password;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "machine_id", referencedColumnName = "id")
private MachineBase machine;
}
Ответы (3 шт):
Переопределите вручную equals и hashcode у обоих классов. Проблема в аннотации @EqualsAndHashCode и @ToString, которые включены в аннотации @Data.
Проблема в трех методах, которые нам приносит аннотация @Data: equals, hashCode и toString. Кроме того, вы получите такую ошибку, если будете сериализовать объекты в json. Дело в том, что когда вы пытаетесь прочитать содержимое первого объекта, вам нужен второй. Но во втором есть ссылка на первый. И там мы входим в рекурсию без условия выхода из нее.
На мой взгляд, самым оптимальным решением будет настроить одностороннюю связь один к одному. Для этого нам надо продумать кто будет вызывать один объект из другого.
В библиотеке Jackson (если вы используете его для сериализации) есть аннотации @JsonBackReference и @JsonManagedReference. Они как раз нужны для того, чтобы определить родительский и дочерний объект и избежать рекурсии при сериализации.