A Home object provides persistence operations for a particular entity class. Suppose we have our Person class:
@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 ClipboardCopied!Toggle word wrapToggle overflow
We can define a personHome component either through configuration:
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Or through extension:
@Name("personHome")
public class PersonHome extends EntityHome<Person> {}
@Name("personHome")
public class PersonHome extends EntityHome<Person> {}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
A Home object provides operations like persist(), remove(), update() and getInstance(). Before you can call remove() or update(), you must set the identifier of the object you are interested in, using the setId() method.
For example, we can use a Home directly from a JSF page:
Copy to ClipboardCopied!Toggle word wrapToggle overflow
This is all the code required to create new Person entries. If we want to be able to display, update, and delete pre-existing Person entries in the database, we need to be able to pass the entry identifier to the PersonHome. An excellent method is through page parameters:
Copy to ClipboardCopied!Toggle word wrapToggle overflow
When we link to the page with no request parameters, the page will be displayed as a Create Person page. When we provide a value for the personId request parameter, it will be an Edit Person page.
If we need to create Person entries with their nationality initialized, we can do so easily. Via configuration:
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Or via extension:
@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 ClipboardCopied!Toggle word wrapToggle overflow
The Country could be an object managed by another Home object, for example, CountryHome.
To add more sophisticated operations (association management, etc.), we simply add methods to 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 ClipboardCopied!Toggle word wrapToggle overflow
The Home object raises an org.jboss.seam.afterTransactionSuccess event when a transaction (a call to persist(), update() or remove()) succeeds. By observing this event, we can refresh our queries when the underlying entities change. If we only want to refresh certain queries when a particular entry is persisted, updated, or removed, we can observe the org.jboss.seam.afterTransactionSuccess.<name> (where <name> is the name of the entity).
The Home object automatically displays Faces messages when an operation succeeds. To customize these messages we can, again, use configuration:
<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 ClipboardCopied!Toggle word wrapToggle overflow
Or extension:
@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 ClipboardCopied!Toggle word wrapToggle overflow
The best way to specify messages is to put them in a resource bundle known to Seam — by default, the bundle named 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 ClipboardCopied!Toggle word wrapToggle overflow
This enables internationalization, and keeps your code and configuration clean of presentation concerns.