高度なカスタマイズ > サービスおよびインフラストラクチャのカスタマイズ > システム生成 > ビジネスオブジェクトのモデル化 > 特殊な永続の構成
  
特殊な永続の構成
GenAsUnPersistable "テーブル"
データベーステーブルにマッピングされているものとして認識されるクラスはすべて、wt.fc.Persistable を拡張する必要があります。GenAsPersistable によって生成される _ クラスは、これを自動的に処理します。GenAsBinaryLink- によって生成される _ クラスは、Persistable を拡張する wt.fc.BinaryLink を実装することによってこれを行います。
永続クラスとして実装されるインタフェースをモデル化するとき、通常は、これらのアノテーションを使用して列 (プロパティ、外部キー、および役割) について説明しますが、実装 (具象) クラスを使用して列を表すこともできます。Windchill のドメインインタフェースではこのアプローチが使用されているため、一連のインタフェースを実装するだけで、処理中 (Workable) やライフサイクル管理 (LifeCycleManaged) などの重要なビジネスロジックを取得できます。
実装クラスでインタフェースのプロパティを永続化する場合は、インタフェースにアノテーションを付ける必要があります。ただし、すべてのインタフェースが常に永続クラスのみによって実装されることを前提としているわけではありません。まれに、インタフェースが永続クラスによって実装されていたり (データの永続化を可能にするためにインタフェースにアノテーションが付けられることが必要になる)、非永続クラスによって実装されていたり (そのクラスが Persistable になることを GenAsPersistableGenAsBinaryLink が確認することが問題になる) します。このようなケースは、GenAsUnPersistable アノテーションを使用して解決できます。永続実装クラスはインタフェースを自動的に永続インタフェースとして扱いますが、非永続実装クラスは無用に永続化されません。
永続クラスと同じように生成によるメリットを生かすため、非永続クラスに GenAsUnPersistable でアノテーションを付けることはできますが、必要ではありません。さらに、外部化ロジックが自動的に提供されるため、クラスが BLOB として永続化される場合には、このアノテーションを活用できます。これは、インスタンスを BLOB にするときに RMI 外部化が使用されるからです。"BLOB として永続化される" とは、クラス全体が永続クラスのテーブルの BLOB 列に保存されることを意味します。オブジェクトを BLOB にすることは回避してください。インスタンスが挿入された後にクラスが変更されている場合は特に、BLOB の読み直しが複雑であることを見落とすおそれがあるからです。wt.fc.NetFactor を実装するクラスを BLOB として保存する場合は、そのクラスを wt.util.Evolvable にする必要があります。
GenAsEnueratedType 列
Windchill では、個別のローカライズ可能な文字列セットのモデル化がサポートされています。Windchill にコンピュータモデルを保存し、それらを desktoplaptop、または server に分類するとします。これを行う方法は次のとおりです。
リスト 12: ComputerType.java
01 package com.acme.example;
02
03 import com.ptc.windchill.annotations.metadata.*;
04
05 @GenAsEnumeratedType
06 public class ComputerType extends _ComputerType {
07 public static final ComputerType DESKTOP = toComputerType("desktop");
08 public static final ComputerType LAPTOP = toComputerType("laptop");
09 public static final ComputerType SERVER = toComputerType("server");
10 }
リスト 13: ComputerTypeRB.rbInfo
01 ResourceInfo.class=wt.tools.resource.EnumResourceInfo
02
03 desktop.value=Desktop
04 desktop.order=10
05
06 laptop.value=Laptop
07 laptop.order=20
08 laptop.defaultValue=true
09
10 server.value=Server
11 server.order=30
これは、次のように GeneratedProperty を使用して Computer クラスに組み込むことができます。
リスト 14: コンピュータタイプの断片
01 @GeneratedProperty(name="type", type=ComputerType.class, initialValue="ComputerType.getComputerTypeDefault()",
02 constraints=@PropertyConstraints(upperLimit=20, required=true))
このクラスは、前述の一般的なフォーマットに従っています (その (生成された) _ クラスを拡張するアノテーション付きクラスです)。GenAsEnumeratedType でアノテーションが付けられているクラスは最終的には wt.fc.EnumeratedType を拡張し、見ておわかりのとおり、多数のメソッドが自動的に生成されます。その主なものに、to<X>(String)get<X>Default() があります (X はクラスの名前です)。すべてのメソッドを表示するには、javap com.acme.example._ComputerType を呼び出します。
リスト 12 の行番号 7 から 9 は、列挙タイプのインスタンスを生成するために toComputerType(...) API に依存する定数宣言です。これらのエントリは、同じディレクトリにある <X>RB.rbInfo という名前の対応する rbInfo ファイルに含まれている必要があります。この rbInfo ファイルは ResourceInfo.class=wt.tools.resource.EnumResourceInfo タイプであり、ローカリゼーションと値の順序付けの両方をサポートしています。
この列挙タイプを GeneratedProperty として組み込みます。initialValue と拘束が使用されていることに注目してください。すべてのコンピュータモデルが 3 つのタイプのいずれかに割り当てられる必要があります。デフォルトのタイプは laptop です。列挙タイプは、単純な文字列として保存 (およびシリアル化) されます (この場合、保存値は desktoplaptop、または server のいずれかになります)。文字列のデフォルトの upperLimit は 200 文字で、かなり長いので (詳細については Javadoc を参照)、より現実的な最大文字数を設定します。
rbInfo ファイルを構築するには、ant -f bin/tools.xml bundle -Dbundle.input=com.acme.example.* を実行します。拡張子は rbInfo である必要があり、大文字と小文字は区別されます。"I" が小文字であれば、バンドルターゲットはこのファイルを無視します。
GenAsPrimitiveType 列
wt.fc.EnumeratedType の Javadoc を参照すると、EnumeratedTypeGenAsPrimitiveType でアノテーションが付けられています。また、アノテーションの唯一の引数は String.class です。
GenAsPrimitiveType アノテーションはシンプルなアノテーションであり、単一の値を必要とします。これは "プリミティブ" タイプと呼ばれ、アノテーション付きクラスが (永続とシリアル化のために) 縮小されたものです。これを使用することはまずありませんが、これは、簡素なフィールドの機能を拡張するクラス (ロジック) を構築する場合のために用意されています。これを使用する場合は、アノテーションの一部としてこのクラスが縮小されて生成されるタイプを指定する必要があるだけではなく、プリミティブタイプを受け取るコンストラクタと現在の値を返すための <type-in-lower-case>Value() メソッドを提供する必要もあります。
詳細については、アノテーションの Javadoc を参照してください。
GenAsDatastoreSequence データベースシーケンス
工場出荷時設定の Windchill は、部品番号とドキュメント番号を自動的に割り当てます。これは、データベースシーケンスを使用して行われます。
リスト 15: MySequence.java
01 package com.acme.example;
02
03 import com.ptc.windchill.annotations.metadata.*;
04
05 @GenAsDatastoreSequence
06 public class MySequence extends _MySequence { }
前と同じように、SQL を生成およびロードする必要があります (また、アノテーション付きクラスを変更するたびに MethodServer を再起動する必要があります)。これが完了すると、次に示すように値を取得できます (次の例は、シーケンス値をまだ取得していないと想定して 1 と 2 を印刷します)。
リスト 16: シーケンス値の取得
01 from com.acme.example import MySequence
02 from wt.fc import PersistenceHelper
03
04 print PersistenceHelper.manager.getNextSequence(MySequence )
05 print PersistenceHelper.manager.getNextSequence(MySequence )
* 
GenAsDatastoreSequence は 4 つの GenAsDatastore アノテーションのうちの 1 つです。