単一方向の一対一の所有関係オブジェクトの実装方法

ここでは、Google App Engine で利用可能な単一方向の一対一の所有関係 (Unidirectional Owned one-to-one relationship) の実装例を示します。 オブジェクトの所有および方向という考え方については、オブジェクトのリレーション を読んでください。

それではさっそく、具体例をみながら説明します。

ここでは車 (Car オブジェクト) がドア (Door オブジェクト) をひとつ所有している場合を例にとって考えましょう。 この場合「親オブジェクト」は Car、「子オブジェクト」は Door です。

Door クラスは次のようにしました。

import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import com.google.appengine.api.datastore.Key;

@PersistenceCapable
public class Door {
  @PrimaryKey
  @Persistent(valueStrategy=IdGeneratorStrategy.IDENTITY)
  private Key key;

  @Persistent
  private String color;

  public Door(String color){
    this.color = color;
  }

  public Key getKey(){
    return key;
  }

  public String getColor(){
    return color;
  }
}

プライマリキーとなる key というフィールドのほか、ドアの色を保持する String 型の color フィールドがあります。

永続オブジェクトとなるために、クラスに @PersistenceCapable を指定しています。 また、key には @PrimaryKey とバリューストラテジーの指定があります。 これらは永続オブジェクトになるために必要なものであって、「子オブジェクトとなるため」のものではありません。 ここまでは One to One Relationship がどうのこうの、ということは入ってきません。

ポイントは Door を子として持つ、Car をどのように実装するか、です。

Car の実装を見てみましょう。

import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import com.google.appengine.api.datastore.Key;

@PersistenceCapable
public class Car {
    @PrimaryKey
    @Persistent(valueStrategy=IdGeneratorStrategy.IDENTITY)
    private Key key;
    
    @Persistent
    private String name;
    
    @Persistent(dependent="true")
    private Door door;
    
    public Car(String name, String doorColor){
      this.name = name;
      this.door = new Door(doorColor);
    }
    
    public Key getKey(){
      return key;
    }
    
    public String getName(){
      return name;
    }
    
    public Door getDoor(){
      return door;
    }
}

Car は Door 型の door フィールドを持っています。これが子オブジェクトを保持するフィールドです。 このように、親オブジェクトが子オブジェクトへの参照を保持することで、一対一の所有関係ができあがります。

また、door が子オブジェクトであり、親に依存していることを示すために、@Persistent(dependent="true") とします。 こうすると、親オブジェクトである Car オブジェクトを削除したときに、自動的に子オブジェクトである Door オブジェクトも削除されます。

逆に言えば、@Persistent(dependent="true") を指定せずに単に @Persistent とすると、 Car オブジェクトを保存したときに、自動的にそのフィールドである Door オブジェクトは保存されるものの、 Car オブジェクトを削除したときには、Door オブジェクトは自動的には削除されず生き残ってしまいます。

以上、ここでは Google App Engine で利用可能な単一方向の一対一の所有関係の実装例を示しました。