Я считаю, что @EmbeddedId
это, вероятно, более многословно, потому что @IdClass
вы не можете получить доступ ко всему объекту первичного ключа с помощью любого оператора доступа к полю. С помощью @EmbeddedId
вы можете сделать так:
@Embeddable class EmployeeId { name, dataOfBirth }
@Entity class Employee {
@EmbeddedId EmployeeId employeeId;
...
}
Это дает четкое представление о полях, составляющих составной ключ, поскольку все они агрегированы в классе, доступ к которому осуществляется через оператор доступа к полю.
Еще одно отличие от @IdClass
и @EmbeddedId
заключается в написании HQL:
С @IdClass
вами напишите:
выберите e.name из Employee e
и при этом @EmbeddedId
надо написать:
выберите e.employeeId.name из Employee e
Вам нужно написать больше текста для того же запроса. Некоторые могут возразить, что это отличается от более естественного языка, подобного тому, который продвигается IdClass
. Но в большинстве случаев понимание того, что данное поле является частью составного ключа, прямо из запроса является неоценимой помощью.
@IdClass
хотя я предпочитаю@EmbeddedId
в большинстве ситуаций (я должен знать это из сеанса Антонио Гонсалвеса. Он предложил использовать@IdClass
в случае, если составной ключевой класс недоступен или поступает из другого модуля или устаревшего кода, в который мы не можем добавить аннотацию. В этих сценариях@IdClass
нам будет проще наш.@IdClass
аннотации, предоставленной @Gaurav, являются той самой причиной, по которой в спецификации JPA перечислены оба метода создания составного ключа ..@IdClass
и@EmbeddidId
Есть три стратегии использования составного первичного ключа:
@Embeddable
и добавьте в свой класс сущности обычное свойство для него, отмеченное значком@Id
.@EmbeddedId
.@Id
и пометьте свой класс сущности с помощью@IdClass
, предоставляя класс вашего класса первичного ключа.Использование
@Id
с классом, помеченным как,@Embeddable
является наиболее естественным подходом.@Embeddable
Тег может быть использован для других ключей вкладываемых значений в любом случае. Он позволяет рассматривать составной первичный ключ как отдельное свойство и разрешает повторное использование@Embeddable
класса в других таблицах.Следующим наиболее естественным подходом является использование
@EmbeddedId
тега. Здесь класс первичного ключа не может использоваться в других таблицах, поскольку он не является@Embeddable
сущностью, но он позволяет нам рассматривать ключ как отдельный атрибут некоторого класса.Наконец, использование из
@IdClass
и@Id
аннотаций позволяет сопоставить класс первичного ключа соединения , используя свойства самого объекта , соответствующие имена свойств в классе первичного ключа. Имена должны соответствовать (нет механизма для переопределения этого), и класс первичного ключа должен соблюдать те же обязательства, что и с двумя другими методами. Единственным преимуществом этого подхода является его способность «скрыть» использование класса первичного ключа от интерфейса включающей сущности.@IdClass
Аннотаций принимает параметр значения типа класса, который должен быть класс для использования в качестве составного первичного ключа. Поля, которые соответствуют свойствам используемого класса первичного ключа, должны быть аннотированы@Id
.Ссылка: http://www.apress.com/us/book/9781430228509
источник
Я обнаружил случай, когда мне пришлось использовать EmbeddedId вместо IdClass. В этом сценарии есть объединенная таблица, в которой определены дополнительные столбцы. Я попытался решить эту проблему, используя IdClass для представления ключа объекта, который явно представляет строки в объединенной таблице. Я не мог заставить это работать таким образом. К счастью, в «Java Persistence With Hibernate» есть раздел, посвященный этой теме. Одно из предложенных решений было очень похоже на мое, но вместо него использовалось EmbeddedId. Я смоделировал свои объекты по образцу тех, что указаны в книге, теперь они ведут себя правильно.
источник
Насколько я знаю, если ваш составной ПК содержит FK, его проще и проще использовать
@IdClass
При этом
@EmbeddedId
вам нужно определить сопоставление для столбца FK дважды, один@Embeddedable
раз и один раз для as, т.е.@ManyToOne
где@ManyToOne
должно быть только чтение (@PrimaryKeyJoinColumn
), потому что у вас не может быть одного столбца, установленного в двух переменных (возможные конфликты).Таким образом, вы должны установить свой FK, используя простой ввод
@Embeddedable
.На другом сайте с
@IdClass
этой ситуацией можно справиться намного проще, как показано в разделе Первичные ключи через отношения OneToOne и ManyToOne :Пример аннотации идентификатора ManyToOne в JPA 2.0
Пример класса идентификатора JPA 2.0
источник
Я думаю, что основным преимуществом является то, что мы могли бы использовать
@GeneratedValue
идентификатор при использовании@IdClass
? Я уверен, что мы не можем использовать@GeneratedValue
для@EmbeddedId
.источник
При использовании составной ключ не должен иметь
@Id
свойства@EmbeddedId
.источник
С EmbeddedId вы можете использовать предложение IN в HQL, например:
FROM Entity WHERE id IN :ids
где id - это EmbeddedId, тогда как получить тот же результат с IdClass больно, вы захотите сделать что-то вродеFROM Entity WHERE idPartA = :idPartA0 AND idPartB = :idPartB0 .... OR idPartA = :idPartAN AND idPartB = :idPartBN
источник