Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com
Answertopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions
Privacy Policy

  




 

 

10.2. Home objects

A Home object provides persistence operations for a particular entity class. Suppose we have our trusty Person class:
@Entity
public class Person {
    @Id private Long id;
    private String firstName;
    private String lastName;
    private Country nationality;
    
    //getters and setters...
}
We can define a personHome component either via configuration:
<framework:entity-home name="personHome" entity-class="eg.Person" />
Or via extension:
@Name("personHome")
public class PersonHome extends EntityHome<Person> {}
A Home object provides the following operations: persist(), remove(), update() and getInstance(). Before you can call the remove(), or update() operations, you must first set the identifier of the object you are interested in, using the setId() method.
We can use a Home directly from a JSF page, for example:
<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>
Usually, it is much nicer to be able to refer to the Person merely as person, so let's make that possible by adding a line to components.xml:
<factory name="person" 
         value="#{personHome.instance}"/>

<framework:entity-home name="personHome" 
                       entity-class="eg.Person" />
(If we are using configuration.) Or by adding a @Factory method to PersonHome:
@Name("personHome")
public class PersonHome extends EntityHome<Person> {
    
    @Factory("person")
    public Person initPerson() { return getInstance(); }
    
}
(If we are using extension.) This change simplifies our JSF page to the following:
<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>
Well, that lets us create new Person entries. Yes, that is all the code that is required! Now, 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. Page parameters are a great way to do that:
<pages>
    <page view-id="/editPerson.jsp">
        <param name="personId" value="#{personHome.id}"/>
    </page>
</pages>
Now we can add the extra operations to our JSF page:
<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>
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.
Suppose we need to create Person entries with their nationality initialized. We can do that easily, via configuration:
<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>
Or by 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);
    }
    
}
Of course, the Country could be an object managed by another Home object, for example, CountryHome.
To add more sophisticated operations (association management, etc), we can just 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();
    }
    
}
The Home object automatically displays faces messages when an operation is successful. 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>
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 "New person #{person.firstName} 
      #{person.lastName} created"; }
    protected String getUpdatedMessage() { return "Person #{person.firstName} 
      #{person.lastName} updated"; }
    protected String getDeletedMessage() { return "Person #{person.firstName} 
      #{person.lastName} deleted"; }
    
}
But the best way to specify the messages is to put them in a resource bundle known to Seam (the bundle named messages, by default).
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
This enables internationalization, and keeps your code and configuration clean of presentation concerns.
The final step is to add validation functionality to the page, using <s:validateAll> and <s:decorate>, but I'll leave that for you to figure out.

 
 
  Published under the terms of the Open Publication License Design by Interspire