Knappsack Archetypes Part 2
In part 1, we looked at the basic structure and configuration of the project that is common in all the archetypes. This time we’ll look at the minimal archetype that contains some more functionality and a number of different classes used to implement that functionality.
The Java EE 6 Minimal Archetype
While there is still only one web page in the project, there are now a few more classes provided. These have been grouped into packages off the main package folder.
Package | Description |
---|---|
bean |
The bean package contains the EntityManager producer and also a dao object for fetching and persisting Person objects as a stateless EJB (and a local interface). |
model |
Contains the JPA model for ther application which in this case is just one Person class |
qualifier |
Contains the qualifier used to specify injection points for the EntityManager |
view |
Contains the backing beans for the JSF view. These beans provide server side logic for the JSF pages, usually by invoking functions on the service beans in the bean package. The HelloBean accepts a user entered name and returns a message. The PersonBean has a person entity that can be modified by a JSF page and then persisted to the database. There is also a method to return the list of previously saved people from the database. |
Layered code
We have a fairly clear separation of concerns with the different packages. The EJBs in the bean
and qualifier
packages don’t have any dependency on JSF while the beans in the view
package are for JSF support only. Such organization means that you could put the contents of the bean and qualifier packages into a separate jar and re-use them with a different view framework. Technically, because they are also POJOs you could use them in a non-EJB environment.
Producing Entity Managers
The EntityManager
is produced in the DataRepositoryProducer
bean by returning the persistence context that was injected into the stateless bean by the container. When an entity manager needs to be injected into an injection point, this method is used to produce one. It is marked as @ConversationScoped
so it can participate in CDI conversations. The @DataRepository
annotation is a qualifier annotation used to mark what kind of entity manager you are producing and therefore can only be injected into injection points with the same annotation. This is useful if there are multiple databases used to distinguish between different entity managers produced.
Service Beans
In the PersonDao
we inject the EntityManager
that is then used in the other methods to save and fetch objects. In EJB 3.1 the default transaction attribute is Required
for EJB methods so we don’t need to specify any transaction handling on the methods.
PersonDao
is injected into the view/PersonBean
class so as the view needs to fetch or update data, the dao can be used to provide those functions.
If there was a mechanism that we could use to provide transactions on CDI (non-EJB) beans, then we wouldn’t really need EJBs, but as it is, we do. Nothing is stopping us from later changing the EJBs to CDI Managed beans with sufficient transaction support.
JPA Model
The only model class we use is the Person
class that has properties for first name, last name and an integer Id value. On the name fields, we have specified a number of validators as well as the column size using annotations. These validators check that the field is not empty, or null and does not have a length greater than 25 characters.
Now we’ve covered the server side code, let’s take a look at the JSF page that uses these beans in home.xhtml
.
JSF Content
The single page in this archetype is split into three different sections that test different parts of the environment.
The first part is producing the hello message from the helloBean
class. The class is annotated with @Named("helloBean")
which lets us reference this bean from the JSF page. The method getHelloMessage()
returns a fixed string which is displayed in the page by using the EL expression #{helloBean.helloMessage}
. This tells JSF to get the helloMessage
property from the bean called helloBean
. The bean name is resolved using an EL expression resolver that looks up the bean name in the beans registered with CDI using the @Named
annotation.
name
property of the helloBean
bean which is then used to return the correct message to the user when the page is re-rendered.
The final section uses JSF and CDI to edit an instance of a Person
object on the CDI backing bean, with JPA persisting the object and Bean Validation providing validation for the JSF page. JPA also returns a list of the people previously saved. The PersonBean
class has the @Named
annotation which gives it the name personBean
and it is marked with a @RequestScoped
annotation. The bean has a person instance that is used as the model for the JSF page input boxes. The text boxes are defined for the first and last names and bound to the person entity on the personBean
bean. Each input has a h:message
JSF tag that reports errors for that input value. This will report errors on the person bean based on the validators we specified on the model. In the JSF page, the Add button calls the savePerson
method on the personBean
backing bean which uses the person dao implementation to persist the person
entity in the backing bean. JSF automatically includes validation specified on the JPA model and will report errors back to the user for invalid input.
Underneath the person data entry, there is a list of names that have already been entered. Just enter a new name and click add to see the new name appear.This is fetched from the backing bean using the dao that is injected into it.
Using the app for yourself
If you want to create a new application from this archetype, you will probably want to delete the following items.
/bean/PersonDao.java /bean/PersonDaoLocal.java /model/Person.java /view/HelloBean.java /view/PersonBean.java
While you may want to re-use the template, or a modified version of it, you won’t need the content in the home.xhtml
file. You can remove the content surrounded by the <ui:define name="content">
tags. Alternatively, you can just create a new project using the jee6-basic-archetype which has none of this additional code.
In the next section we’ll start looking at the JPA model and pre-defined data in the sandbox archetype.
2 thoughts on “Knappsack Archetypes Part 2”
Comments are closed.
Andy,
In this site: http://smokeandice.blogspot.com/2009/12/cdi-and-declarative-transactions.html there’s a interesting article on what can you do CDI with Declarative Transactions without EJB.
Hey Waldemar,
Thanks for the link, I have read that excellent post, and even referred to it in some post or other.
My take on it is that short term, we’re on our own, medium term, Seam or more likely Weld-extensions will provide for transactions in CDI without EJBs. Longer term Java EE 7 will probably have transactions on CDI beans. So I didn’t bother adding my own versions in the archetypes simply because it would be obsolete in a few months.
There are a couple of other good posts on that site that I keep meaning to write about (the JPA discussion in one of the posts comments).
Cheers,
Andy Gibson