Workshop では、Bean コードの中で指定することによって、CMP エンティティ Bean の新規作成時に主キーを自動的に生成できます。これにより、ユーザが主キーの値を指定する必要がなくなります。ベンダ固有のさまざまな方法 (Oracle、SQLServer、または SQLServer2000 を使用) で主キーを自動生成できます。または、ベンダに依存しない命名済シーケンス テーブルを使用することもできます。自動生成された主キーの型は必ず Integer または Long になります。
この節のトピックは、以下のとおりです。
Oracle では、ユニークな主キーを自動的に生成するための sequence
ユーティリティが用意されています。このユーティリティを使用して、CMP エンティティ Bean の主キーを自動生成するには、シーケンス テーブルを作成し、@AutomaticKeyGeneration アノテーションを使用してこのテーブルを指定する必要があります。
使用している Oracle データベースで、主キーを作成するシーケンス テーブルを作成する必要があります。次の例を参照してください。
create sequence myOracleSequence start with 1 nomaxvalue;
これにより、1 から始まり 2、3 と続いていく主キー値のシーケンスが作成されます。例のシーケンス テーブルは、デフォルトのインクリメントである 1 を使用していますが、increment キーワードを、increment by 3 のように指定することでインクリメントを変更できます。インクリメントを変更した場合は、次のように @AutomaticKeyGeneration アノテーションの cacheSize 属性にまったく同じ値を指定する必要があります。
@AutomaticKeyGeneration(cacheSize = "3", name = "myOracleSequence", type = AutomaticKeyGeneration.AutomaticKeyGenerationType.SEQUENCE)
CMP Bean のプロジェクト設定で自動的なテーブル作成を指定した場合は、エンティティ Bean のデプロイ時にシーケンス テーブルが自動的に作成されます。詳細については、「weblogic.ejbgen.JarSettings」を参照してください。CMP エンティティ Bean の定義の詳細については、後述の節を参照してください。
SQL Server では、IDENTITY
キーワードを使用して、主キーの自動生成を指示することができます。次の例は、最初の主キー値が 1 で、インクリメントが 1 という一般的なシナリオを示しています。
CREATE TABLE Customer (Customer_ID int IDENTITY(1,1), FirstName varchar(30) LastName varchar(30))
CMP エンティティ Bean の定義では、使用する自動キー ジェネレータのタイプとして SQLServer (2000) を指定する必要があります。キャッシュ サイズも指定できます。
@AutomaticKeyGeneration(cacheSize = "3", name = "mySqlServerID", type = AutomaticKeyGeneration.AutomaticKeyGenerationType.IDENTITY)
CMP Bean のプロジェクト設定で自動的なテーブル作成を指定した場合は、エンティティ Bean のデプロイ時にシーケンス テーブルが自動的に作成されます。詳細については、@JarSettings アノテーションを参照してください。CMP エンティティ Bean の定義の詳細については、後述の節を参照してください。
命名済シーケンス テーブルは、主キーの生成に専用のテーブルが使用されるという点で Oracle の sequence 機能と似ています。ただし、命名済シーケンス テーブルを使用した方法はベンダに依存しません。この方法で主キーを自動生成するには、次の例のように 2 つの SQL 文を使用して命名済シーケンス テーブルを作成します。
CREATE Table MyNamedSequence (SEQUENCE number); INSERT into MyNamedSequence VALUES (0);
CMP エンティティ Bean の定義では、使用する自動キー ジェネレータのタイプとして命名済シーケンス テーブルを指定する必要があります。キャッシュ サイズも指定できます。
@AutomaticKeyGeneration(cacheSize = "100", name = "MyNamedSequence", type = AutomaticKeyGeneration.AutomaticKeyGenerationType.SEQUENCE_TABLE)
CMP Bean のプロジェクト設定で自動的なテーブル作成を指定した場合は、エンティティ Bean のデプロイ時にシーケンス テーブルが自動的に作成されます。詳細については、@JarSettings アノテーションを参照してください。CMP エンティティ Bean の定義の詳細については、次節を参照してください。
注意 :命名済シーケンス テーブルに対して cacheSize 値を指定すると、エンティティ Bean の作成用に一連のユニークな値が予約されます。新しいキャッシュが必要になると、最初の一連のユニークな値は完全に使用されたという前提で 2 番目の一連のユニークな値が予約されます。このため、主キー値が必ずしも連続していないという可能性は残りますが、主キー値が常にユニークであることが保証されます。たとえば、最初の一連の値が 10 ~ 20 の場合、最初の一連の値が実際にはエンティティ Bean の作成にすべて使用されていなくても、2 番目の一連の値は 21 ~ 30 になります。
主キー ジェネレータのいずれかを使用する CMP エンティティ Bean を定義する場合、@AutomaticKeyGeneration アノテーションを使用して、主キーを取得する主キー ジェネレータ テーブルの名前を指定します。また、自動生成された主キーを設定および取得するために、主キー フィールドの型を Integer または Long に定義する必要があります。ただし、ejbCreate メソッドは、主キー値を引数として取りません。代わりに、EJB コンテナが適切な主キーをエンティティ Bean レコードに追加します。
次の例は、エンティティ Bean の一例です。この Bean は上記の命名済シーケンス オプションを使用しており、ejbCreate メソッドは主キーを取っていません。@AutomaticKeyGeneration(cacheSize = "1", name = "NamedSequence", type = AutomaticKeyGeneration.AutomaticKeyGenerationType.SEQUENCE_TABLE) @Entity(defaultTransaction = Constants.TransactionAttribute.SUPPORTS, primKeyClass = "Integer", ejbName = "Customer_APK", dataSourceName = "samplesDataSource", tableName = "ejb_customer", abstractSchemaName = "Customer") @FileGeneration(localClass = Constants.Bool.TRUE, localClassName = "AutomaticPK_CustomerLocal", localHome = Constants.Bool.TRUE, localHomeName = "AutomaticPK_CustomerHome", remoteClass = Constants.Bool.FALSE, remoteHome = Constants.Bool.FALSE, remoteHomeName = "CustomerRemoteHome", remoteClassName = "CustomerRemote", valueClass = Constants.Bool.FALSE, valueClassName = "CustomerValue", pkClass = Constants.Bool.TRUE) @JndiName(local = "ejb.AutomaticPK_CustomerLocalHome") public abstract class Customer_APK extends GenericEntityBean implements EntityBean { @CmpField(column = "FirstName") @LocalMethod() public abstract String getFirstName(); @LocalMethod() public abstract void setFirstName(String arg); @CmpField(column = "LastName") @LocalMethod() public abstract String getLastName(); @LocalMethod() public abstract void setLastName(String arg); @CmpField(primkeyField = Constants.Bool.TRUE, column = "Customer_ID") @LocalMethod() public abstract Integer getCustomer_ID(); @LocalMethod() public abstract void setCustomer_ID(Integer arg); public java.lang.Integer ejbCreate(java.lang.String FirstName, java.lang.String LastName) { setFirstName(FirstName); setLastName(LastName); return null; } public void ejbPostCreate(java.lang.String FirstName, java.lang.String LastName) { } }