JPA @MapsID, получая ошибку org.hibernate.TransientPropertyValueException: объект ссылается на несохраненный временный экземпляр - PullRequest
0 голосов
/ 02 мая 2020

Пользователь:

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column
    private String name;

    @OneToOne(mappedBy = "user")
    private Address address;


    //Getters and setters
}

Адрес:

@Entity
public class Address {
    @Id
    private Long id;

    @Column
    private String country;

    @OneToOne
    @JoinColumn(name = "id")
    @MapsId
    private User user;


    //Getters and setters
}

Ниже приведена полученная ошибка:

2020-05-02 02:33:42 - Uncaught Runtime Exception
org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance

Классы пользователей и адресов имеют один и тот же первичный ключ.

Не могли бы вы сказать, что еще мне нужно изменить в приведенном выше коде? Я написал выше на основе некоторого примера, который я нашел, я буду рад, если кто-то сможет объяснить мне, что происходит внутри

РЕДАКТИРОВАТЬ:

Я пытаюсь Вставьте Пользователь , имеющий RequestBody как ниже , затем перед лицом выше исключения.

{
    "name": "john",
    "adddress": {
        "country": "US"
    }
}

Ответы [ 2 ]

0 голосов
/ 04 мая 2020

Вам необходимо сделать 2 модификации:

  • добавить каскад @OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
  • убедитесь, что оба:
    • адрес указывает на пользователя
    • пользователь указывает на адрес

Последнее обычно выполняется через пользовательский установщик, который устанавливает обе стороны отношения

public void setAddress(Address address) {
    if (address == null) {
        if (this.address != null) {
            this.address.setUser(null);
        }
    }
    else {
        address.setUser(this);
    }
    this.details = details;
}

Пожалуйста, убедитесь, что это вызывается при десериализации JSON для ваших сущностей.

0 голосов
/ 02 мая 2020

Вы должны каскадировать отношения. В объекте User измените отношение на:

@OneToOne(mappedBy = "user", cascade = CascadeType.ALL)

Это будет распространять любую операцию от родительского объекта к дочернему объекту, ie, от User до Address здесь. Таким образом, когда вы сохраните объект User, соответствующий объект Address также будет сохранен и т. Д.


Дальнейшее чтение:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...