valid,invalid

関心を持てる事柄について

多対多で自己再帰の関連を持つテーブルのEntity

多対多(Many To Many)で自己再帰的(self recursive)な関係をEbean の Model で表現するのに苦戦した。
あまり良い例ではないけど、
person には似てる人(similarPerson)が複数いる、という設定で書いてみた。
person と person の多対多を解消する中間テーブルは similar_person として定義してみる。

@Entity
public class Person {
@Id
public Long id;

@ManyToMany
@JoinTable(name = "similar_person",
joinColumns = @JoinColumn(name = "person_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "similar_person_id", referencedColumnName = "id"))
public List similarPersons;
}

ポイントは @JoinTable の引数の joinColumns と inverseJoinColumns 。
最初これらを書かずにいたら、similar_person テーブルで列名 person_id が重複しています と怒られた。

考えてみたらどちらも外部参照先 (person.id) は同じなんだから、列名指定せずに自動生成したらそうなるよな…。

上記のクラスを定義した上で Evolution を実行すると、下記SQL が自動生成される。

# --- Created by Ebean DDL
# To stop Ebean DDL generation, remove this comment and start using Evolutions

# --- !Ups

create table similar_person (
person_id bigint not null,
similar_person_id bigint not null,
constraint pk_similar_person primary key (person_id, similar_person_id))
;

alter table similar_person add constraint fk_similar_person_person_01 foreign key (person_id) references person (id) on delete restrict on update restrict;

alter table similar_person add constraint fk_similar_person_person_02 foreign key (similar_person_id) references person (id) on delete restrict on update restrict;

# --- !Downs

SET REFERENTIAL_INTEGRITY FALSE;

drop table if exists similar_person;


JPA をちゃんと理解してなかったのでけっこうハマった。

【参考】

JPA – Recursive ManyToMany-Relationship | stuetzpunkt -