こんにちは、mabuiです。
JPAでは推奨されていないみたいですが、サロゲートキーを使用しない、
ナチュラルキーのみの中間テーブルの作り方の紹介です。
テーブル定義
例えばwebサービスに良くあるような、お気に入りのページをストックする機能を作る場合、
お気に入り情報のエンティティを下記のようにテーブル定義します。
1 2 3 4 5 |
create table favorite ( page_id bigint not null, user_id bigint not null, primary key (page_id, user_id) ) engine=InnoDB; |
page_idとuser_idは多対多の関係性です。
お気に入り情報の追加と削除機能を実装する場合、
お気に入り削除時に、データ量削減のためレコードを削除するとします。
この時にサロゲートキーを使用していると、キーの値が飛び飛びになり、
なんか気持ち悪いです。
複合主キーの定義
そこで複合主キーの定義を行うわけですが、
JPAで主キーを指定する@id アノテーションは複合主キーでは使用できないため、
下記のようにエンティティクラスの実装を行います。
1 2 3 4 5 |
@Embeddable data class FavoritePK( val userId: Long, val pageId: Long ): Serializable |
1 2 3 4 5 6 |
@Entity @Table(name = "favorite") data class Favorite( @EmbeddedId val favoritePK: FavoritePK ) |
複合主キーにしたいフィールドをFavoritePKクラスとして、
@Embeddableを使って単一のフィールドにします。
Favoriteクラスには、FavoritePKのフィールドを@EmbeddedIdでid指定します。
これで、記事の最初に乗っけたテーブル定義にマッピングできます。
ちなみに、テーブルアクセス時にJPAのRepositoryインターフェースを使用する場合は、
FavoritePKのインスタンスを生成し、それを引数に使用します。
1 2 |
val favorite = favoriteRepository.findOneByFavoritePK(FavoritePK(pageId, userId)) |