Uważam, że @EmbeddedId
jest to prawdopodobnie bardziej szczegółowe, ponieważ @IdClass
nie możesz uzyskać dostępu do całego obiektu klucza podstawowego za pomocą dowolnego operatora dostępu do pola. Używając @EmbeddedId
możesz zrobić w ten sposób:
@Embeddable class EmployeeId { name, dataOfBirth }
@Entity class Employee {
@EmbeddedId EmployeeId employeeId;
...
}
Daje to jasne pojęcie o polach, które tworzą klucz złożony, ponieważ wszystkie są zagregowane w klasie, do której dostęp uzyskuje się za pośrednictwem operatora dostępu do pola.
Kolejna różnica między @IdClass
i w @EmbeddedId
przypadku pisania HQL:
Z @IdClass
tobą piszesz:
wybierz e.name z Employee e
a z @EmbeddedId
tobą trzeba napisać:
wybierz e.employeeId.name z Employee e
Musisz napisać więcej tekstu dla tego samego zapytania. Niektórzy mogą twierdzić, że różni się to od bardziej naturalnego języka, takiego jak promowany przez IdClass
. Jednak w większości przypadków zrozumienie bezpośrednio z zapytania, że dane pole jest częścią złożonego klucza, jest nieocenioną pomocą.
@IdClass
chociaż wolę@EmbeddedId
w większości sytuacji (poznali ten z sesji Antonio Goncalves .Co zasugerował to możemy użyć@IdClass
w przypadku kompozytu Klasa klucza jest niedostępna lub pochodzi z innego modułu lub starszego kodu, w którym nie możemy dodać adnotacji. W tych scenariuszach@IdClass
da nam sposób nasz.@IdClass
adnotacji podanej przez @Gaurav są tym samym powodem, dla którego specyfikacja JPA wymienia obie metody tworzenia klucza złożonego ..@IdClass
i@EmbeddidId
Istnieją trzy strategie używania złożonego klucza podstawowego:
@Embeddable
i dodaj do swojej klasy jednostki normalną właściwość oznaczoną znakiem@Id
.@EmbeddedId
.@Id
i oznacz klasę jednostki za pomocą@IdClass
, podając klasę klasy klucza podstawowego.Użycie
@Id
z klasą oznaczoną jako@Embeddable
jest najbardziej naturalnym podejściem.@Embeddable
Tag może być używany do kluczowych niż podstawowe wartości niezabudowany tak. Umożliwia traktowanie złożonego klucza podstawowego jako pojedynczej właściwości i umożliwia ponowne użycie@Embeddable
klasy w innych tabelach.Kolejnym najbardziej naturalnym podejściem jest użycie
@EmbeddedId
tagu. W tym przypadku klasa klucza podstawowego nie może być używana w innych tabelach, ponieważ nie jest ona@Embeddable
jednostką, ale pozwala nam traktować klucz jako pojedynczy atrybut jakiejś klasy.Wreszcie, użycie adnotacji
@IdClass
i@Id
umożliwia nam mapowanie złożonej klasy klucza podstawowego przy użyciu właściwości samej jednostki odpowiadającej nazwom właściwości w klasie klucza podstawowego. Nazwy muszą się zgadzać (nie ma mechanizmu nadpisywania tego), a klasa klucza podstawowego musi honorować te same obowiązki, co w przypadku pozostałych dwóch technik. Jedyną zaletą tego podejścia jest możliwość „ukrycia” użycia klasy klucza podstawowego przed interfejsem encji otaczającej.@IdClass
Adnotacja przyjmuje parametr wartość typu Class, która musi być klasa być stosowany jako związek klucz podstawowy. Wszystkie pola, które odpowiadają właściwościom używanej klasy klucza podstawowego, muszą być opatrzone adnotacją@Id
.Źródła: http://www.apress.com/us/book/9781430228509
źródło
Odkryłem wystąpienie, w którym musiałem użyć EmbeddedId zamiast IdClass. W tym scenariuszu istnieje tabela łączenia, która ma zdefiniowane dodatkowe kolumny. Próbowałem rozwiązać ten problem, używając IdClass do reprezentowania klucza jednostki, która jawnie reprezentuje wiersze w tabeli łączenia. Nie mogłem sprawić, żeby to działało w ten sposób. Na szczęście „Java Persistence With Hibernate” zawiera sekcję poświęconą temu tematowi. Jedno z proponowanych rozwiązań było bardzo podobne do mojego, ale zamiast tego korzystało z EmbeddedId. Wymodelowałem swoje obiekty na podstawie tych z książki, teraz zachowuje się poprawnie.
źródło
O ile wiem, jeśli twój złożony PK zawiera FK, jest łatwiejszy i prostszy w użyciu
@IdClass
Z tym,
@EmbeddedId
że musisz dwukrotnie zdefiniować mapowanie dla swojej kolumny FK, raz w środku@Embeddedable
i raz na przykład,@ManyToOne
gdzie@ManyToOne
ma być tylko do odczytu (@PrimaryKeyJoinColumn
), ponieważ nie możesz ustawić jednej kolumny w dwóch zmiennych (możliwe konflikty).Musisz więc ustawić swój FK za pomocą prostego wpisywania
@Embeddedable
.W innej witrynie korzystanie z
@IdClass
tej sytuacji może być znacznie łatwiejsze, jak pokazano w Kluczach podstawowych przez relacje OneToOne i ManyToOne :Przykład adnotacji identyfikacyjnej JPA 2.0 ManyToOne
Przykład klasy ID JPA 2.0
źródło
Myślę, że główną zaletą jest to, że możemy użyć
@GeneratedValue
identyfikatora podczas korzystania z@IdClass
? Jestem pewien, że nie możemy użyć@GeneratedValue
do@EmbeddedId
.źródło
Klucz złożony nie może mieć
@Id
właściwości, gdy@EmbeddedId
jest używany.źródło
Dzięki EmbeddedId możesz użyć klauzuli IN w HQL, na przykład:
FROM Entity WHERE id IN :ids
gdzie id to EmbeddedId, podczas gdy osiągnięcie tego samego wyniku z IdClass jest trudne, będziesz chciał zrobić coś takiegoFROM Entity WHERE idPartA = :idPartA0 AND idPartB = :idPartB0 .... OR idPartA = :idPartAN AND idPartB = :idPartBN
źródło