JPA Спецификация гласит:
Семантика операции слияние , примененной к объекту X, следующая:
Если X является отсоединенным объектом, состояние X копируется в ранее существующий экземпляр управляемого объекта X 'с таким же идентификатором или создается новая управляемая копия X' из X.
Если X является новым экземпляром объекта, создается новый экземпляр управляемого объекта X ', а состояние X копируется в новый экземпляр управляемого объекта X'.
Если X является удаленным экземпляром объекта, операция слияния создаст IllegalArgumentException
(или фиксация транзакции завершится неудачей).
Если X является управляемым объектом, этооднако операция слияния игнорируется, но операция слияния каскадно объединяется с объектами, на которые ссылаются отношения из X, если эти отношения были аннотированы значением аннотации элемента cascade=MERGE
или cascade=ALL
.
Для всех объектов Y, на которые ссылаются отношенияиз X, имеющего значение элемента каскада cascade=MERGE
или cascade=ALL
, Y рекурсивно объединяется как Y '.Для всех таких Y, на которые ссылается X, X 'устанавливается на ссылку Y'.(Обратите внимание, что если X управляется, то X является тем же объектом, что и X '.)
Если X является объектом, объединенным с X', со ссылкой на другой объект Y, где cascade=MERGE
или cascade=ALL
не указано, тогда навигация той же ассоциации из X 'дает ссылку на управляемый объект Y' с таким же постоянным идентификатором, как Y.
Как видите, здесь нет магии.Состояние отдельного экземпляра копируется во вновь созданный управляемый экземпляр.Поскольку у вашего отсоединенного экземпляра есть пустой список, управляемый экземпляр также будет иметь его.
Дальнейшее поведение зависит от принадлежности отношения, поскольку представление в базе данных отражает сторону отношения с владельцем:
- Если
Team
является владельцем, отношения между Team
и Player
s будут уничтожены во время сброса (но сам Player
выживет, если у вас не будет orphanRemoval = true
в ваших отношениях). - В противном случае наличие пустого списка в
Team
не повлияет на базу данных.
Если вы обновите Team
до очистки контекста, все свойства Team
будут перезаписаны значениями из базы данных, поэтому список Player
s восстанавливается (поскольку пустой список игроков еще не был сброшен).
Если вы звоните flush()
до вызова refresh()
, а Team
является стороной-владельцем, список будет пустым, поскольку уничтожение связей было передано в базу данных во время flush()
.