Как решить отношения (Java + Spring + JPA + Hibernate Mappings)

Я прочитал много тем о сопоставлении с помощью JPA + Hibernate, но, попробовав несколько вещей, не могу получить ожидаемого результата.

Я объявил все свои однонаправленные отношения, так как не вижу необходимости двунаправленно их направлять

Мои объекты для отображения: У клиента есть Страна и список адресов.

@Table(name = "Client")
@Entity
public class Client
{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
    @GenericGenerator(name = "native", strategy = "native")
    private Long id;

    @OneToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST })
    @JoinColumn(name = "country_id", unique = false, /*nullable = false,*/ insertable = true, updatable = false, foreignKey = @ForeignKey(name = "country_fk0"))
    private Country country;

    @OneToMany(cascade = { CascadeType.PERSIST }, orphanRemoval = true)
    @JoinColumn(name = "address_id",/* nullable = false,*/ foreignKey = @ForeignKey(name = "address_fk0"))
    private List<Address> address;

//GETTERS / SETTERS
}

затем я оценю клиента и сохраню его в новой таблице ClientProcessed, которая будет ссылаться на объекты Addresses и Country, хранящиеся в моем объекте Client.

@Table(name = "ProcessedClient")
@Entity
public class ProcessedClient
{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
    @GenericGenerator(name = "native", strategy = "native")
    private Long id;

    @OneToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST })
    @JoinColumn(name = "client_evaluation_id", unique = false, /*nullable = false,*/ insertable = true, updatable = false, foreignKey = @ForeignKey(name = "evaluation_fk0"))
    private ClientEvaluation evaluation;

    @OneToOne(cascade = { CascadeType.MERGE })
    @JoinColumn(name = "country_id", unique = false, /*nullable = false,*/, foreignKey = @ForeignKey(name = "country_fk1"))
    private Country country;

    @OneToMany(cascade = { CascadeType.MERGE}, orphanRemoval = true)
    @JoinColumn(name = "address_id",/* nullable = false,*/ foreignKey = @ForeignKey(name = "address_fk2"))
    private List<Address> addresses;

//GETTERS / SETTERS
}

Итак, когда я это делаю:

Country country = new Country();
country.setId(1l); // (DB ID)

// I do the same with addresses

ProcessedClient processedClient = new ProcessedClient();
processedClient.setAddresses(addresses);
processedClient.setCountry(country);

this.getDao().save(processedClient);

Результат:

org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing

Спасибо

Но в этом случае мой объект представлен в базе данных. Это происходит потому, что у вас есть коллекция в вашей сущности, и в этой коллекции есть один или несколько элементов, которых нет в базе данных. Указав вышеуказанные параметры, вы указываете hibernate сохранять их в базе данных при сохранении их родителя.

Matheus 11.02.2019 17:53
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
27
1

Ответы 1

Из документации:

Hibernate определяет и поддерживает следующие состояния объекта:

  • Transient — объект является временным, если он только что был создан с помощью оператора new и не связан с Hibernate Session. ...
  • Постоянный — постоянный экземпляр имеет представление в базе данных и значение идентификатора.

Вы должны загрузить страну из базы данных по идентификатору, а затем установить его в ProcessedClient.

Другие вопросы по теме