net.java.aoのすべてのアノテーションの概要(javadocの日本語訳)

net.java.aoのアノテーションの概要を日本語訳しました。対象のアノテーションは下表のとおりです。

アノテーション 翻訳対象のjavadoc
Accessor https://activeobjects.dev.java.net/api/net/java/ao/Accessor.html
Generator https://activeobjects.dev.java.net/api/net/java/ao/Generator.html
Implementation https://activeobjects.dev.java.net/api/net/java/ao/Implementation.html
ManyToMany https://activeobjects.dev.java.net/api/net/java/ao/ManyToMany.html
Mutator https://activeobjects.dev.java.net/api/net/java/ao/Mutator.html
OneToMany https://activeobjects.dev.java.net/api/net/java/ao/OneToMany.html
OneToOne https://activeobjects.dev.java.net/api/net/java/ao/OneToOne.html
Polymorphic https://activeobjects.dev.java.net/api/net/java/ao/Polymorphic.html
Preload https://activeobjects.dev.java.net/api/net/java/ao/Preload.html
Searchable https://activeobjects.dev.java.net/api/net/java/ao/Searchable.html
Transient https://activeobjects.dev.java.net/api/net/java/ao/Transient.html

以下、本文となります。

Accessor

特定のフィールドがアクセッサであることを表します。これにより二つのことが可能になります:

  • get/setの規約に従わないこと
  • 自動生成されるフィールド名のオーバライド(例えば「getURI」という名前のメソッドは(デフォルトでは)「uRI」というフィールド名を生成する。おそらく、本当に必要なフィールド名は「uri」でしょう。このアノテーションによりこのようなフィールド名を使用できます。)

Used to mark a particular field as an accessor. This allows two things:

* Non-compliance with the get/set convention
* Overriding of the auto-generated field name (e.g. a method named "getURI" would generate (by default) a field name of "uRI". Most likely, the desired field name was in fact "uri". This annotation allows such field names

Generator

INSERT時に生成される値を含むメソッド(とそのデータベースフィールド)を指定します。ValueGeneratorクラスによる生成アルゴリズムを値として指定します。これにより、UUIDキーやその他のアプリケーションで生成する必要のある値などを実装することができます。

Marks a specific method (and thus, database field) to contain a generated value on INSERT. The precise value and generation algorithm is specified by the ValueGenerator class. This can be used to implement functionality like UUID keys and other values which must be generated in the application layer.

これはINSERT文の値を生成するだけであり、UPDATEやSELECTなどそのほか文は対象外です。いずれそのような機能が追加されることはあるかもしれません。しかし、今のところUUIDの主キーなどを想定して設計されており、アプリケーション層の更新時のことは想定されていません。

This only generates values for INSERT statements, not UPDATE, SELECT or any such statement. It is likely that down the road, such functionality will be added. However, at the moment the designed use-case is something like UUID primary keys, rather than an application-layer ON UPDATE.

Implementation

定義済みのエンティティの実装を指定します。例:

Used to specify a defined implementation for an entity. Example:

@Implementation(PersonImpl.class)
 public interface Person extends Entity {
     // ...
 }

パラメータは必須です。

The parameter is not optional.

ManyToMany

メソッドが多対多関連をもつことを示します。当該メソッドの戻り値として、(指定された型の先にある)多対多関連先の型を使うよう、ActiveObjectsに知らせます。例えば、

Marks a method as relevant only to a many-to-many relation. This informs ActiveObjects that the return value for the method in question should be determined from a many-to-many relation through the specified type onto the type in the return value. For example:

public interface Person {
     // ...
     
     @ManyToMany(Authorship.class)
     public Book[] getBooks();
 }

したがって、以下のようなクエリの結果がgetBooks()メソッドの戻り値になります。

Thus the return value of the getBooks() method would be determined by a query something like the following:

SELECT bookID FROM authorships WHERE personID = ?

where()句に条件を指定すると、エンティティの検索条件に追加されます。例えば、多対多関連を以下の形で表すこともできます。

If the where() clause is specified, it will be used in addition to the base, necessary criterion to determine the returned entities. Thus, the many-to-many relation could be referenced in the following way:

public interface Person {
     // ...
     
     @ManyToMany(value=Authorship.class, where="deleted = FALSE")
     public Book[] getBooks();
 }

これは以下のようなクエリになるでしょう。

This would lead to a query like the following:

SELECT bookID FROM authorships WHERE personID = ? AND (deleted = FALSE)

このvalue()パラメータは必須です。

The value() parameter is not optional.

Mutator

メソッドがデータベースフィールドのミューテータであることを表します。メソッドに対応するフィールドを手動で指定するためにも使用できます(たいていはそのように使用します)。例えば以下のようになります:

Marks a specific method as a mutator of a database field. This annotation can also be (and usually is) used to manually specify a field name which corresponds to a method; as in the following example:

public Company extends Entity {
     // ...
     
     @Mutator("url")
     public void setURL(URL url);
     // ...
 }

OneToMany

メソッドが一対多関連を持つことを示します。当該メソッドの戻り値として、一対多関連先の型を使うよう、ActiveObjectsに知らせます。例えば、

Marks a method as relevant only to a one-to-many relation. This informs ActiveObjects that the return value for the method in question should be determined from a one-to-many relation onto the type in the return value. For example:

public interface Company {
     // ...
     
     @OneToMany
     public Person[] getEmployees();
 }

したがって、以下のようなクエリの結果がgetEmployees()メソッドの戻り値になります。

Thus the return value of the getEmployees() method would be determined by a query something like the following:

SELECT id FROM people WHERE companyID = ?

where()句に条件を指定すると、エンティティの検索条件に追加されます。例えば、一対多関連を以下の形で表すこともできます。

If the where() clause is specified, it will be used in addition to the base, necessary criterion to determine the returned entities. Thus, the one-to-many relation could be referenced in the following way:

public interface Company {
     // ...
     
     @OneToMany(where="deleted = FALSE")
     public Person[] getEmployees();
 }

これは以下のようなクエリになるでしょう。

This would lead to a query like the following:

SELECT id FROM people WHERE companyID = ? AND (deleted = FALSE)

OneToOne

メソッドが一対一関連を持つことを示します。当該メソッドの戻り値として、一対一関連先の型を使うよう、ActiveObjectsに知らせます。例えば、

Marks a method as relevant only to a one-to-one relation. This informs ActiveObjects that the return value for the method in question should be determined from a one-to-one relation onto the type in the return value. For example:

public interface User {
     // ...
     
     @OneToOne
     public Password getPassword();
 }

したがって、以下のようなクエリの結果がgetPassword()メソッドの戻り値になります。

Thus the return value of the getPassword() method would be determined by a query something like the following:

SELECT id FROM passwords WHERE userID = ?

where()句に条件を指定すると、エンティティの検索条件に追加されます。例えば、一対一関連を以下の形で表すこともできます。

If the where() clause is specified, it will be used in addition to the base, necessary criterion to determine the returned entities. Thus, the one-to-one relation could be referenced in the following way:

public interface User {
     // ...
     
     @OneToOne(where="deleted = FALSE")
     public Password getPassword();
 }

これは以下のようなクエリになるでしょう。

This would lead to a query like the following:

SELECT id FROM passwords WHERE userID = ? AND (deleted = FALSE)

Polymorphic

指定されたエンティティ型をポリモーフィックとしてタグ付けします。その結果、指定された型は他のエンティティ(指定されたインタフェースを継承するエンティティ)のポリモーフィックな上位型となり、テーブルには対応付けされなくなります。通常の継承では、下位型がテーブルに対応付けらることはありませんが、ポリモーフィック型の継承では、ActiveObjects中で上位型として「型付け」されたデータベースフィールドに、下位型のインスタンスを記憶できるようになります。

Tags a given entity type as polymorphically abstract. This means that the given type will not peer to any table, but rather represent a polymorphic supertype to other entities (entities which extend the given interface). Unlike conventional inheritence, which also causes the supertype to not peer to a table, polymorphic type inheritence allows instances of the subtype to be stored in the database into fields which are "typed" in ActiveObjects as the supertype. All of this is really much simpler than it sounds:

public interface Person extends Entity {
     public Computer getComputer();
     public void setComputer(Computer computer);
 }
 
 @Polymorphic
 public interface Computer extends Entity {
     public float getSpeed();
     public void setSpeed(float speed);
 }
 
 public interface Mac extends Computer {}
 public interface PC extends Computer {}

この場合、Computerはデータベースのテーブルに対応付けされません。また、PersonはgetComputer()に対応するフィールドへの外部キーを持ちません。エンティティ型がポリモーフィックであれば、下位型がPersonであるかのようにポリモーフィックに使用できます。このデータベースへの対応付けは、本質的に抽象クラスの概念に似ています。

In this case, Computer does not correspond with any table in the database. Likewise, Person has no foreign keys for the corresponding field to getComputer(). When an entity type is polymorphic, its subtypes can be used polymorphically as they are in Person. This is essentially the conceptual analog of an abstract class when mapped into the database.

Preload

当該の型の行を取得する際に、SELECT句に常に追加すべきフィールドを指定します。特定の型のエンティティの取得時にいつもアクセスされるるフィールドがある場合、そのフィールドは先読みの最有力候補になります。例:
Specifies a list of fields which should be appended to the SELECT clause every time a row of the type in question is retrieved. If the developer knows that every time an entity of a certain type is retrieved, certain fields will be accessed, this is a prime candidate for preloading. For example:

@Preload("name")
 public interface Person extends Entity {
     public String getName();
     public void setName(String name);
     
     // ...
 }
 
 // ...
 manager.find(Person.class, "age > 12");

このコードでは以下のようなクエリが実行されます。

This code will run a query something like the following:

SELECT id,name FROM people WHERE age > 12

複数のフィールドを指定することもできます。

A list of fields may also be specified:

@Preload({"firstName", "lastName"})
 public interface Person extends Entity {
     public String getFirstName();
     public void setFirstName(String firstName);
     
     public String getLastName();
     public void setLastName(String lastName);
     
     // ...
 }
 
 // ...
 manager.find(Person.class, "age > 12");

これにより以下のようなクエリが実行されます。

This produces a query like the following:

SELECT id,firstName,lastName FROM people WHERE age > 12
  • クエリに対し、すべてのフィールドを読み込むように強制するこような指定も可能です。このように、@Preloadは、ActiveObjectsの遅延読み込み基盤を上書きするための主要なメカニズムです。

* may also be specified to force queries to load all fields. As such, @Preload is the primary mechanism provided by ActiveObjects to override its lazy-loading underpinnings.

このフラグはヒントです。@Preloadの値を無視してそのままのクエリを実行する(EntityManager.findWithSQL(Class, String, String, Object...)が行うような)問い合わせもあります。

This flag is a hint. There are still queries (such as those executed by EntityManager.findWithSQL(Class, String, String, Object...)) which will ignore the @Preload values and simply execute a vanilla query.

Searchable

Luceneのインデックスでフルテキスト検索をするメソッドをタグ付けするために使用します。このアノテーションは、SearchableEntityManagerのインスタンスと組み合わせることで、意味をもちます。組み合わせなければ、ActiveObjectsはこのアノテーションを無視します。例:

Used to tag methods as being full-text searchable within a Lucene index. This annotation is only relevant when used in conjunction with an instance of SearchableEntityManager. Otherwise, it is ignored by ActiveObjects. Example:

public interface Post extends Entity {
     public String getTitle();
     public void setTitle(String title);
     
     @Searchable
     @SQLType(Types.BLOB)
     public String getBody();
     
     @Searchable
     @SQLType(Types.BLOB)
     public void setBody(String body);
 }
 
 // ...
 SearchableEntityManager manager = ...;
 manager.search(Post.class, "my search string");    // returns search results as Post[]

At the moment, it is impossible to specify the Lucene field and type which will be used in the index. By default, tablename.fieldname is utilized to determine the Lucene field. More features are planned for this annotation in future.

Transient

値キャッシュにフィールドを保存したくないメソッドに対して指定します。外部プロセスによるフィールドの値の更新を知りたい場合や、フィールドが巨大化してキャッシュできなることがある場合には、これを使用します。

Marks a method such that its field should not be stored within the value cache. This allows for scenarios when the you know that the value of the field will be updated in an external process or perhaps the value will be too large to be reasonably cached.