...
Scrollbar |
---|
...
So, you fill in all the fields, submit the form (without validation errors) and voila: you get back the same form, blanked out. What happened, and where did the data go?
...
Well, since we're creating objects, we might as well store them somewhere ... in a database. We're going to quickly integrate Tapestry with Hibernate as the object/relational mapping layer, and ultimately store our data inside a HyperSQL (HSQLDB) database. HSQLDB is an embedded database engine and requires no installation – it will be pulled down as a dependency via mavenby Maven.
Re-configuring the Project
...
Code Block | ||||
---|---|---|---|---|
| ||||
<dependencies> <dependency> <groupId>org.apache.tapestry</groupId> <artifactId>tapestry-hibernate</artifactId> <version>${tapestry-release-version}</version> </dependency> <dependency> <groupId>org.hsqldb <hsqldb</groupId> <artifactId>hsqldb</artifactId> <version>2.3.2</version> </dependency> ... </dependencies> |
...
But what entities? Normally, the available entities are listed inside hibernate.cfg.xml, but that's not necessary with Tapestry; in another example of convention over configuration, Tapestry locates all entity classes inside the entities package ("com.example.tutorialtutorial1.entities" in our case) and adds them to the configuration. Currently, that is just the Address entity.
...
Code Block | ||||
---|---|---|---|---|
| ||||
package com.example.tutorialtutorial1.entities; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import org.apache.tapestry5.beaneditor.NonVisual; import org.apache.tapestry5.beaneditor.Validate; import com.example.tutorialtutorial1.data.Honorific; @Entity public class Address { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @NonVisual public Long id; public Honorific honorific; @Validate("required") public String firstName; @Validate("required") public String lastName; public String street1; public String street2; @Validate("required") public String city; @Validate("required") public String state; @Validate("required,regexp") public String zip; public String email; public String phone; } |
...
Code Block | ||||
---|---|---|---|---|
| ||||
package com.example.tutorialtutorial1.pages.address; import com.example.tutorialtutorial1.entities.Address; import com.example.tutorialtutorial1.pages.Index; import org.apache.tapestry5.annotations.InjectPage; import org.apache.tapestry5.annotations.Property; import org.apache.tapestry5.hibernate.annotations.CommitAfter; import org.apache.tapestry5.ioc.annotations.Inject; import org.hibernate.Session; public class CreateAddress { @Property private Address address; @Inject private Session session; @InjectPage private Index index; @CommitAfter Object onSuccess() { session.persist(address); return index; } } |
...
As a little preview of what's next, let's display all the Addresses entered by the user on the Index page of the application. After you enter a few names, it will look something like:
Adding the Grid to the Index page
...
A minimal Grid is very easy to add to the template. Just add this near the bottom of Index.tml:
Code Block | ||||
---|---|---|---|---|
| ||||
<t:grid source="addresses"
include="honorific,firstName,lastName,street1,city,state,zip,phone"/>
|
Note that the Grid component accepts many of the same parameters that we used with the BeanEditForm. Here we use the include parameter to specify the properties to show, and in what order.
Now And all we have to do is supply the addresses property in the Java code. Here's how Index.java should look now:
Code Block | ||||
---|---|---|---|---|
| ||||
package com.example.tutorial1.pages; import java.util.List; import org.apache.tapestry5.ioc.annotations.Inject; import org.hibernate.Session; import com.example.tutorial1.entities.Address; public class Index { @Inject private Session session; public List<Address> getAddresses() { return session.createCriteria(Address.class).list(); } } |
Here, we're using the Hibernate Session object to find all Address objects in the database. Any sorting that takes place will be done in memory. This is fine for now (with only a handful of Address objects in the database). Later we'll see how to optimize this for very large result sets.
...
We have lots more to talk about: more components, more customizations, built-in Ajax support, more common design and implementation patterns, and even writing your own components (which is easy!).
Check out the many Tapestry resources available on
...
the Documentation
...
page, including
...
the Getting Started and FAQ pages and the Cookbook
...
. Be sure to peruse the User Guide, which provides comprehensive details on nearly every Tapestry topic
...
. Finally, be sure to visit (and bookmark) Tapestry JumpStart, which provides a nearly exhaustive set of tutorials.
Scrollbar |
---|