e hënë nëntor 14, 2005 I gave you a short primer on Java EE 5 persistence in my last blog entry. Now it's time for a demo. I'll show you how to setup the persistence framework in web application and create a POJO class that represents data from a database table. Then I will execute an EJBQL query to get object from database. In the last step I will use the new JSF component palette to generate a page that displays object in table.
I'll be using a NetBeans Java EE 5 daily build from November 13 and build 26 of GlassFish open source Java EE application server, you also need JDK 1.5.
I should repeat that support for Java EE 5 is NOT part of NetBeans 5.0, it will be in the next release of NetBeans and is now being developed on a "javaee5" branch.
Register GlassFish in NetBeans using Tools>Server Manager menu. To register GlassFish use the Sun Java Systems Application Server as a server type. NetBeans will help you to create a new domain for the server, use the "Create Personal Domain" option.
Create a new web application project, select GlassFish server and set J2EE version "Java EE 5". Click next and add Java Server Faces support.
Now let's add persistence support into this project. This will be just a few clicks in a wizard, but since I did not cover the persistence unit in the intro let me first describe it here.
Persistence unit defines where and how to persist your classes. The definition of persistence unit consists of:
In this example we will only specify the data source. We will use defaults for everything else.
We could specify the parameters of data source directly in your persistence.xml, setting properties like jdbc.connection.string, jdbc.driver, jdbc.user, etc.
But in this example I will be using a data source that is defined by the application server, the persistence unit will just reference it by its name. This will make it easier to move the application from one application server and database to another, for example between development, test and production environments.
Now back to our demo. Select menu File>New File (Ctrl+N). Select Persistence Unit template in category Persistence:
Type the name of persistence unit ("demo1"), and keep the default for provider:
Persistence units are defined in persistence.xml file. The content of generated file is:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="demo1" transaction-type="JTA">
<jta-data-source>jdbc/__default</jta-data-source>
<properties/>
</persistence-unit>
</persistence>
|
Let's keep the default name of data source jdbc/__default for the demo. Normally you'd go to server admin tool and setup a data source there. But GlassFish has a data source with name jdbc/__default and a derby database connection pool registered. Setup up of database is the next step.
GlassFish bundles derby open source database and this is what I will use for this demo. NetBeans has a module that supports derby. Download the "Derby Database Support" module from the development update center. Use menu Tools>Update Center.
First, start the database using menu Tools>Derby Database>Start Derby Server. Then connect to the database:
The data source jdbc/__default in application server uses the following database URL: jdbc:derby://localhost:1527/sun-appserv-samples;create=true. Use sa for both user name and password and on the next panel select schema APP. This will add a the new connection in Runtime tab and you can execute database scripts on it:
Note the new SQL editor with syntax highlighting, toolbar, etc. that we added in NetBeans 5.0:
Here is the complete script for the table and for inserting some data (insert each line separately). Refresh the list of tables and select View Data from popup menu on DIVECHARTERS table to verify everything is fine. Yes, these are some cool scuba diving trips with my favorite dive shop in Beaufort, NC :-)
Ok, we are done with the database.
Click New.. (Ctrl+N) and select Persistence Entity template in category Persistence. Type class name "Divecharters" and package name "data" and click Finish.
Now add properties for table columns:
@Entity
public class Divecharters {
private int id;
private Date departure;
private String boat;
private String diveSite;
private String description;
private int maxDepth;
private double price;
private int capacity;
...
}
|
Use menu Refactor>Encapsulate Fields to create getters and setters for these fields.
Later on NetBeans will support generation of persistence classes from DB tables, similarly as the "CMP from Database" in NetBeans 4.1 and 5.0.
We will create a JSF managed bean that will select all instances of Divecharters using EJBQL query. Then we will edit the welcomeJSF.jsp to display them.
Use New.. (Ctrl+N), select the template JSF Managed Bean in category Web. Type class name "PersonController", package "beans" and set scope to "session".
We will use EntityManager the get the persistent data. EntityManager is the central access point to the persistence API. It allows you to create and run queries, persist objects, manage transactions, etc.
The server will inject EntityManager for the PersistenceUnit we defined in Step 2. We will use it to query for all instances of Divecharters class:
public class PersonController {
@PersistenceContext(unitName="demo1")
EntityManager em;
public List getCharters() {
return em.createQuery("select object(d) from Divecharters as d").getResultList();
}
...
|
This means that our JSF managed bean PersonController will have a property charters. We can now add a JSF data table into welcomeJSF.jsp to render the list of charters. We started to work on a set of templates and palette items to simplify development and prototyping of simple CRUD applications. This is experimental at this point but it comes handy for the demo (give me feedback!). The first preview are two JSF palette items: JSF Form and JSF Data Table:
The code generated in page looks like this:
<f:view>
<h:form>
<h1><h:outputText value="List"/></h1>
<h:dataTable value="#{PersonController.charters}" var="item">
<h:column>
<f:facet name="header">
<h:outputText value="Id"/>
</f:facet>
<h:outputText value="#{item.id}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Departure"/>
</f:facet>
<h:outputText value="#{item.departure}"/>
</h:column>
...
|
Run the application:
I promised earlier that I will keep you in touch with what new stuff we are working on in Java EE support. Today I would like to write about object relational mapping. This is a very important part of Java EE 5 that we will support in netbeans.next. I will post a tutorial about creating simple persistence classes in a javaee5 preview build soon, so take this as a small intro. It is not a complete description of all features, just a quick overview for someone who is not familiar with this area.
Object relational mapping (ORM) is about representing data from database as Java beans. The advantage of using ORM over traditional JDBC is that you do not have to think it terms of database tables, columns, foreign keys, etc. All you use is Java beans, properties and collections of other objects.
Java Persistence API (JSR 220) is a new standard API for ORM. Unlike the EJB 2.x entity classes the new persistence API does not require the context of an EJB module and can be used in a web module or even in a Java SE application.
Here is how it compares to some other frameworks for accessing data:
Java Persistence API does not require the persistent classes to implement any special interfaces, they are just "plain old Java objects" (POJO) marked with annotations.
The mapping between the persistent classes and database tables is also controlled by annotations (or an xml file if you prefer that). But most importantly is has some reasonable defaults, for example a persistent class will be mapped to a table of the same name, its properties will be mapped to columns with the same names, etc. Here is a small example:
CREATE TABLE APP.PERSON ( ID INT NOT NULL, NAME VARCHAR(40), AGE INT NOT NULL ) |
...
@Entity
public class Person {
private int id;
private String name;
private int age;
@Id(generate = GeneratorType.AUTO)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
...
}
|
What if you do need to control the mapping? Let's say the Java class needs to be the same it was but the table is different. You would do something like this:
CREATE TABLE APP.HR_EMPLOYEE ( ID INT NOT NULL, EMP_NAME VARCHAR(40), EMP_AGE INT NOT NULL ) |
...
@Entity()
@Table(name="HR_EMPLOYEES")
public class Person {
...
@Column (name="EMP_NAME")
public String getName() {
return name;
}
...
}
|
Being POJOs, persistent classes do not need to live within any container. This greatly simplifies writing automated tests or using the persistence classes in combination with other technologies. You can create instances just like this:
Person p = new Person ();
p.setId (41);
p.setName ("Dent Arthur Dent");
...
|
The last nice feature I will mention is that you can write queries to retrieve data from database in terms of Java classes, without reference to the actual relational tables. This is using EJBQL:
select object(p) from Person as p
|
Note that this query will work unchanged even if you map the Person class to table "HR_EMPLOYEES" as shown above.
The basic support for developing persistent classes is in setup and packing of the "Persistence unit" (more about that in the tutorial) and providing templates for persistent classes, code completion for persistence API, etc.
More advanced features we plan to work on include code completion for database metadata (table name, columns, etc.), EJBQL editor, generation of Java classes from an existing database schema, etc.
I wish we had something like this for other project types. The code completion only shows classes that are already on classpath and if you want to use a different class you have to know where it is. Of course the trick used here is that the universe of possible libraries is known upfront, it's just the APIs of modules in the target NetBeans platform, so the dialog knows where to look for them. But I would be happy if this worked for the libraries, projects that are currently open and perhaps recently open projects.
Maybe it could even be more integrated into code completion. If the class is not found in completion instead of "No Suggestions" you would have get a "Look for the class in libraries" item... Maybe this is also an answer to Geertjan's comment: "I don't like [...] that you need to manually put the EJB on the web application's classpath."
( Nën 06 2005, 10:34:13 MD EST )
Permalink
Comments [0]
No, it is not part of NetBeans 5.0. Yes, I too wanted everything yesterday :-) but the specs and the application servers are not complete either. Anyway, there are daily builds of the next version of NetBeans available from NetBeans download page which already support creation of EJB 3.0 beans and deployment to GlassFish and Jboss. We will be adding functionality as it gets added into our favorite server and as time permits (we still have some work on NetBeans 5.0).
I wrote a small tutorial about how to get the build and create your first JavaEE 5 application. Check it out and send feedback to nbj2ee@netbeans.org or add comments bellow.
I will be posting more about the progress on JavaEE 5 support in this blog.
( Nën 05 2005, 01:07:01 PD EST )
Permalink
Comments [9]