taediumの日記

2008-11-17

[][]Gen-Ddlで外部キー制約の生成を制御する

追記

(※)小林さんに「外部キー」と「外部キー制約」は意味が違うよねという指摘を受けたのでちょっと全体的に言葉を置き換えてみました。


Gen-Ddlで外部キー生成を抑制するアイデアのつづきです。

いろいろアイデアがでて練った結果、次の2つの機能を提供することになりました。

  • ビルドファイルで、外部キー制約の自動生成のON/OFFを指定可能にする
  • アノテーションで個別に外部キー制約の生成を制御できるようにする

この2つを組み合わせると、外部キー制約を多用するパターンとほとんど使用しないパターンの両方に柔軟に対応できます。以下、例です。

ビルドファイルで自動生成を有効にする場合

Gen-Ddlタスクは外部キー制約の自動生成がデフォルトで有効です。個別に生成を抑制するには@ReferentialConstraint(false)を使います(このアノテーションS2JDBCアノテーションになります)。基本的にはすべての関連で外部キー制約を使いたいけど、一部分だけはずしたいという場合に便利です。

たとえば、次のエンティティがあるとします。

@Entity
public class Employee {

  @Id
  public Integer id;
  public Integer departmentId;
  public Integer addressId;

  @ManyToOne
  public Department department;
 
  @ReferentialConstraint(false)
  @OneToOne
  public Address address;
}

addressプロパティに@ReferentialConstraint(false)を指定しています。この場合、このアノテーションによりADDRESSテーブルへの外部キー制約の生成が抑制されます。したがって、DEPARTMENTテーブルへの外部キー制約だけが自動生成されます。

ビルドファイルで自動生成を無効にする場合

外部キー制約を基本使わないプロジェクトではこっちが便利でしょう。

外部キー制約の自動生成を無効にするには、Gen-DdlタスクのautoGenerateForeignKey属性に"false"を指定して実行します。

<gen-ddl
    classpathDir="build/classes"
    rootPackageName="examples"
    autoGenerateForeignKey="false"
    classpathRef="classpath"
/>

これで、外部キー制約が自動的に生成されることはなくなります。ただし、@ReferentialConstraint(true)を使えば、個別に生成することができます。

こんなエンティティがあるとします。

@Entity
public class Employee {

  @Id
  public Integer id;
  public Integer departmentId;
  public Integer addressId;

  @ManyToOne
  public Department department;
 
  @ReferentialConstraint(true)
  @OneToOne
  public Address address;
}

addressプロパティに@ReferentialConstraint(true)を指定しています。この場合、ADDRESSテーブルへの外部キー制約のみが生成されます。(DEPARTMENTテーブルへの外部キー制約は生成されません。)

この機能は次のバージョンに含まれます。