Какое значение имеет право владения недвижимостью и как CASCADE работает с двумя сторонами в JPA? - PullRequest
0 голосов
/ 30 августа 2018

У меня есть две таблицы. Транзакции и ошибки. Между транзакциями и ошибками существует отношение «один ко многим». Это двунаправленное отношение, и ошибки являются собственниками, поскольку @JoinColumn указывается в классе ошибок. Я хочу понять, что именно означает "СОБСТВЕННЫЕ" отношения. Скажи в данный момент у меня,

  • ОБРАБОТАНО (столбец в СДЕЛАХ), установленный на N
  • ACTIVE (столбец в ОШИБКАХ) установлен на 1

Сценарий 1: Теперь давайте предположим, что мы выполняем следующий код.

transactions.setProcessed("Y");
errors.setActive(0);
transactions.setErrors(errors);
entityManager.merge(transactions);

Я понимаю, что для поля PROCESSED будет установлено значение "Y" в транзакциях, но будет ли поле ACTIVE в ошибках также установлено в 0 или нет, если транзакции НЕ являются СОБСТВЕННОЙ стороной отношения?

Сценарий 2: С другой стороны, если мы выполним следующее:

errors.setActive(0);
transactions.setProcessed("Y");
errors.setTransactions(transactions);
entityManager.merge(errors);

Я понимаю, что поле ACTIVE, зарегистрированное в ОШИБКАХ, будет установлено в 0, но будет ли поле ОБРАБОТАНО в СДЕЛАХ также установлено в "Y", учитывая, что ОШИБКИ - СОБСТВЕННАЯ сторона отношения?

Как каскадные типы JPA связаны с подобными сценариями?

Ответы [ 2 ]

0 голосов
/ 31 августа 2018

В двунаправленных отношениях вы определяете отображение. Когда вы вносите изменения в это отображение, очевидно, что произойдет - внешний ключ будет обновлен. Поскольку существует только одно сопоставление, не может быть никакого конфликта (многие поставщики JPA будут выдавать ошибки, если обнаружат, что у вас имеется более одного доступного для записи сопоставления для поля).

При двунаправленных отношениях этот контроль менее очевиден. В двунаправленном отношении транзакции-ошибки предположим, что это двунаправленное сопоставление OneToOne, а для Transaction1 задано значение Error1 и наоборот. Допустим, ваше приложение определяет, что Transaction1 должен быть указан вместо Error2, и изменяет ссылку. Если ссылка Error1 на Transaction1 не исправлена, чтобы отразить эту ситуацию, для JPA существует проблема в определении того, какое значение ввести во внешний ключ. Это где собственность вступает в игру. Обладающая сторона считается доступным для записи отображением, и изменения в ней управляют полями внешнего ключа. В OneToMany стороной-владельцем обычно является обратная ссылка ManyToOne, поскольку она более естественна, поскольку внешний ключ в любом случае находится в таблице, содержащей ManyToOne. Если вы вносите изменения, чтобы добавить ошибку в транзакцию, но не изменяете ошибку, чтобы также ссылаться на эту транзакцию, ваша объектная модель будет не синхронизирована с тем, что входит в базу данных - внешний ключ в ошибке не будет изменен, но объект транзакции будет отображать ошибку в своем списке, пока он не будет обновлен или перезагружен из базы данных.

Каскадирование - это нечто, не связанное с владением. Это просто означает, что операция (сохранить, объединить, удалить, обновить) применяется к объекту, на который ссылается отношение. При использовании cascade.all вызова em.refresh (транзакция) транзакция и все указанные ошибки будут обновлены из базы данных. Любые отношения ошибок, имеющие каскадную настройку ALL или REFRESH, также будут обновлены и так далее. JPA должен обнаружить, что он уже обновил ссылочный экземпляр Transaction, если вы поместите его в обратные ссылки, но зачем рисковать. Как правило, каскадные параметры следует размещать только в отображениях, где они необходимы, чтобы избежать непреднамеренных последствий. Если вы не уверены, нужно ли это, оставьте это, пока не будете уверены. Такие вещи, как ленивая выборка и другая оптимизация, могут вызвать всевозможные странные и трудные для поиска ошибки, когда кто-то идет и ставит каскадное обновление везде.

В вашем примере вы можете поместить каскадное слияние в корневую сущность, которую ваше приложение будет передавать. Любые изменения, внесенные в этот график, легко воспринимаются одним вызовом слияния без необходимости слияния на каждом отдельном листе. Однако то, как ваша модель будет построена и сериализована, повлияет на слияние, поэтому обычно каскадные параметры помещаются только в отношения root-> Leaf, чтобы избежать проблем, где root -> leaf -> root 'где root! = Root'. Если у вас есть каскадное слияние с обеих сторон, состояние root 'может перезаписать ваши изменения в root.

0 голосов
/ 30 августа 2018

Когда мы говорим, что «Ошибки» являются владельцем, это означает, что внешний ключ отношения находится в таблице «Ошибки» (которую вы делаете через @JoinColumn). Таким образом, владельцем является отношение, в котором будет присутствовать ссылочный столбец другого объекта. Вы можете определить обратную сторону отношения, указав @OneToMany в сущности Транзакции.

Теперь вторая часть вашего вопроса, касающаяся обновления транзакций и ошибок. На мой взгляд, вы можете обновить Список, связанный с транзакцией, применив соответствующий режим каскада (сохранить, удалить и т. Д.), Что означает, что вы можете указать в своей сущности транзакции @OneToMany(cascade=CASCADETYPE.MERGE) при указании обратной связи. Таким образом, если вы обновите строку транзакции, соответствующие строки ошибок также могут быть обновлены.

Однако я не думаю, что это хорошая практика каскадировать другим способом, т.е. если вы обновляете дочернюю сущность, родительская сущность также должна обновляться, так как это может привести ко многим несоответствиям данных

...