Home オブジェクトは特定のエンティティクラスに永続性操作を行います。 Person クラスについて考えてみましょう。
@Entity
public class Person {
@Id private Long id;
private String firstName;
private String lastName;
private Country nationality;
//getters and setters...
}
@Entity
public class Person {
@Id private Long id;
private String firstName;
private String lastName;
private Country nationality;
//getters and setters...
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
personHome コンポーネントを定義するには、以下のように設定を通じて行うか
<framework:entity-home name="personHome" entity-class="eg.Person" />
<framework:entity-home name="personHome" entity-class="eg.Person" />
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
拡張で行います。
@Name("personHome")
public class PersonHome extends EntityHome<Person> {}
@Name("personHome")
public class PersonHome extends EntityHome<Person> {}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
Home オブジェクトは persist()、 remove()、 update()、 getInstance() のような動作を提供します。 remove() または update() を呼び出す前に、setId() メソッドを用いて対象のオブジェクトの識別子を設定する必要があります。
たとえば、 Home を JSF ページから直接利用することができます。
<h1>Create Person</h1>
<h:form>
<div>
First name: <h:inputText value="#{personHome.instance.firstName}"/>
</div>
<div>
Last name: <h:inputText value="#{personHome.instance.lastName}"/>
</div>
<div>
<h:commandButton value="Create Person"
action="#{personHome.persist}"/>
</div>
</h:form>
<h1>Create Person</h1>
<h:form>
<div>
First name: <h:inputText value="#{personHome.instance.firstName}"/>
</div>
<div>
Last name: <h:inputText value="#{personHome.instance.lastName}"/>
</div>
<div>
<h:commandButton value="Create Person"
action="#{personHome.persist}"/>
</div>
</h:form>
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
Person は person で参照できると便利なため、components.xml にその行を加えます (設定を使用している場合)。
<factory name="person" value="#{personHome.instance}"/>
<framework:entity-home name="personHome" entity-class="eg.Person" />
<factory name="person" value="#{personHome.instance}"/>
<framework:entity-home name="personHome" entity-class="eg.Person" />
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
拡張を使用している場合は、 PersonHome に @Factory メソッドを追加できます。
@Name("personHome")
public class PersonHome extends EntityHome<Person> {
@Factory("person")
public Person initPerson() {
return getInstance();
}
}
@Name("personHome")
public class PersonHome extends EntityHome<Person> {
@Factory("person")
public Person initPerson() {
return getInstance();
}
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
これで以下のように JSF ページの記述が簡単になります。
<h1>Create Person</h1>
<h:form>
<div>
First name: <h:inputText value="#{person.firstName}"/>
</div>
<div>
Last name: <h:inputText value="#{person.lastName}"/>
</div>
<div>
<h:commandButton value="Create Person"
action="#{personHome.persist}"/>
</div>
</h:form>
<h1>Create Person</h1>
<h:form>
<div>
First name: <h:inputText value="#{person.firstName}"/>
</div>
<div>
Last name: <h:inputText value="#{person.lastName}"/>
</div>
<div>
<h:commandButton value="Create Person"
action="#{personHome.persist}"/>
</div>
</h:form>
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
これが新しい Person のエントリを作成するために必要なすべてのコードです。 データベースの既存の Person エントリを表示、更新、削除できるようにしたい場合は PersonHome にそのエントリの識別子を渡すことが必要です。 これを行うにはページパラメータの使用が適しています。
<pages>
<page view-id="/editPerson.jsp">
<param name="personId" value="#{personHome.id}"/>
</page>
</pages>
<pages>
<page view-id="/editPerson.jsp">
<param name="personId" value="#{personHome.id}"/>
</page>
</pages>
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
これで JSF ページにこれらの機能を追加することができます。
<h1>
<h:outputText rendered="#{!personHome.managed}" value="Create Person"/>
<h:outputText rendered="#{personHome.managed}" value="Edit Person"/>
</h1>
<h:form>
<div>
First name: <h:inputText value="#{person.firstName}"/>
</div>
<div>
Last name: <h:inputText value="#{person.lastName}"/>
</div>
<div>
<h:commandButton value="Create Person" action="#{personHome.persist}"
rendered="#{!personHome.managed}"/>
<h:commandButton value="Update Person" action="#{personHome.update}"
rendered="#{personHome.managed}"/>
<h:commandButton value="Delete Person" action="#{personHome.remove}"
rendered="#{personHome.managed}"/>
</div>
</h:form>
<h1>
<h:outputText rendered="#{!personHome.managed}" value="Create Person"/>
<h:outputText rendered="#{personHome.managed}" value="Edit Person"/>
</h1>
<h:form>
<div>
First name: <h:inputText value="#{person.firstName}"/>
</div>
<div>
Last name: <h:inputText value="#{person.lastName}"/>
</div>
<div>
<h:commandButton value="Create Person" action="#{personHome.persist}"
rendered="#{!personHome.managed}"/>
<h:commandButton value="Update Person" action="#{personHome.update}"
rendered="#{personHome.managed}"/>
<h:commandButton value="Delete Person" action="#{personHome.remove}"
rendered="#{personHome.managed}"/>
</div>
</h:form>
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
要求パラメータがないページにリンクする場合、 Create Person としてページが表示されます。 personId 要求パラメータに値を与えると Edit Person ページが表示されます。
nationality を初期化して Person エントリを作成しなければならない場合を考えてみましょう。これも簡単にできます。設定を使う場合は、以下のとおりです。
<factory name="person" value="#{personHome.instance}"/>
<framework:entity-home name="personHome" entity-class="eg.Person"
new-instance="#{newPerson}"/>
<component name="newPerson" class="eg.Person">
<property name="nationality">#{country}</property>
</component>
<factory name="person" value="#{personHome.instance}"/>
<framework:entity-home name="personHome" entity-class="eg.Person"
new-instance="#{newPerson}"/>
<component name="newPerson" class="eg.Person">
<property name="nationality">#{country}</property>
</component>
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
また、拡張で行うには次のようにします。
@Name("personHome")
public class PersonHome extends EntityHome<Person> {
@In Country country;
@Factory("person")
public Person initPerson() {
return getInstance();
}
protected Person createInstance() {
return new Person(country);
}
}
@Name("personHome")
public class PersonHome extends EntityHome<Person> {
@In Country country;
@Factory("person")
public Person initPerson() {
return getInstance();
}
protected Person createInstance() {
return new Person(country);
}
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
Country は、例えば、CountryHome という別の Home オブジェクトの管理下のオブジェクトとすることもできます。
アソシエーションの管理など、より洗練された操作を実現するのも PersonHome にメソッドを追加するだけでできるようになります。
@Name("personHome")
public class PersonHome extends EntityHome<Person> {
@In Country country;
@Factory("person")
public Person initPerson() {
return getInstance();
}
protected Person createInstance() {
return new Person(country);
}
public void migrate() {
getInstance().setCountry(country);
update();
}
}
@Name("personHome")
public class PersonHome extends EntityHome<Person> {
@In Country country;
@Factory("person")
public Person initPerson() {
return getInstance();
}
protected Person createInstance() {
return new Person(country);
}
public void migrate() {
getInstance().setCountry(country);
update();
}
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
トランザクションが成功すると (persist()、 update()、 または remove() への呼び出し)、 Home オブジェクトは org.jboss.seam.afterTransactionSuccess イベントを引き起こします。 このイベントを監視することで元になるエンティティが変更された場合にクエリをリフレッシュすることができます。 任意のエンティティの永続化、 更新、 削除が行われたときに特定のクエリをリフレッシュしたいだけの場合は org.jboss.seam.afterTransactionSuccess.<name> を監視します (<name> がそのエンティティ名です)。
Home オブジェクトは操作が成功すると自動的に Faces のメッセージを表示します。 メッセージをカスタマイズする場合も次のように設定を使用します。
<factory name="person" value="#{personHome.instance}"/>
<framework:entity-home name="personHome" entity-class="eg.Person"
new-instance="#{newPerson}">
<framework:created-message>
New person #{person.firstName} #{person.lastName} created
</framework:created-message>
<framework:deleted-message>
Person #{person.firstName} #{person.lastName} deleted
</framework:deleted-message>
<framework:updated-message>
Person #{person.firstName} #{person.lastName} updated
</framework:updated-message>
</framework:entity-home>
<component name="newPerson" class="eg.Person">
<property name="nationality">#{country}</property>
</component>
<factory name="person" value="#{personHome.instance}"/>
<framework:entity-home name="personHome" entity-class="eg.Person"
new-instance="#{newPerson}">
<framework:created-message>
New person #{person.firstName} #{person.lastName} created
</framework:created-message>
<framework:deleted-message>
Person #{person.firstName} #{person.lastName} deleted
</framework:deleted-message>
<framework:updated-message>
Person #{person.firstName} #{person.lastName} updated
</framework:updated-message>
</framework:entity-home>
<component name="newPerson" class="eg.Person">
<property name="nationality">#{country}</property>
</component>
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
拡張で行うには以下のようにします。
@Name("personHome")
public class PersonHome extends EntityHome<Person> {
@In Country country;
@Factory("person")
public Person initPerson() {
return getInstance();
}
protected Person createInstance() {
return new Person(country);
}
protected String getCreatedMessage() {
return createValueExpression("New person #{person.firstName}
#{person.lastName} created");
}
protected String getUpdatedMessage() {
return createValueExpression("Person #{person.firstName}
#{person.lastName} updated");
}
protected String getDeletedMessage() {
return createValueExpression("Person #{person.firstName}
#{person.lastName} deleted");
}
}
@Name("personHome")
public class PersonHome extends EntityHome<Person> {
@In Country country;
@Factory("person")
public Person initPerson() {
return getInstance();
}
protected Person createInstance() {
return new Person(country);
}
protected String getCreatedMessage() {
return createValueExpression("New person #{person.firstName}
#{person.lastName} created");
}
protected String getUpdatedMessage() {
return createValueExpression("Person #{person.firstName}
#{person.lastName} updated");
}
protected String getDeletedMessage() {
return createValueExpression("Person #{person.firstName}
#{person.lastName} deleted");
}
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
メッセージ定義における最良の方法は Seam に対して既知のリソースバンドル (デフォルトでは messages という名前のバンドル) にそのメッセージを定義することです。
Person_created=New person #{person.firstName} #{person.lastName} created
Person_deleted=Person #{person.firstName} #{person.lastName} deleted
Person_updated=Person #{person.firstName} #{person.lastName} updated
Person_created=New person #{person.firstName} #{person.lastName} created
Person_deleted=Person #{person.firstName} #{person.lastName} deleted
Person_updated=Person #{person.firstName} #{person.lastName} updated
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
この方法により国際化に対応でき、コードや設定ファイルの外観を良い状態に保ちます。