Java Persistence - Kennesaw State University



Java Persistence

7.1 Persistence Basics

7.1.1 Introduction

Java objects that represent an application's data model must undergo some transformation in order for the information they contain to be saved in a database. The traditional method of persisting object information to a database is to use the Java Database Connectivity API (JDBC). JDBC allow Java programs to interact with a relational database by exposing a programming interface that allows the programmer to embed SQL statements into an application's source code. To save an object to a database the programmer would create a SQL statement that mapped object data into table columns and then execute the SQL statement. Some of the drawbacks to this early approach include:

• Programmers must be proficient with SQL in addition to Java in order to persist data.

• Embedding SQL in the program means that the database-specific code might be spread out through multiple files in an application, making changes and debugging difficult

• Programmers must deal with time-consuming tasks like determining if a particular record already exists in the database. This leads to a lot of redundant boiler-plate code.

• Complex data structures and relationships can be difficult and time-consuming to map by hand.

Some time later the J2EE specification introduced Entity Beans 2.x. While they were a step in the right direction, programmers found them to be prohibitively complex. In response to this the Enterprise Java Beans 3 specification completely did away with Entity Beans and replaced it with JPA. Although JPA has some complexity (transforming an object into something that can be used efficiently by a relation database is a complex problem), it is much simpler than previous attempts.

JPA bridges the two separate domains of relational databases and object-oriented programming by using object-relational mapping (ORM). JPA takes the objects you specify and converts them automatically to rows in a relational database, saving the time and hassle of writing all the boilerplate code involved in opening connections, updating database relations, and tidying up after the connections.

Java and SQL cover different domains and represent data in different ways. For example, relations in a DBMS cannot be nested. That is, a table cannot contain or encapsulate another table the way a Java object can contain another object. If an e-commerce site is using JPA to save orders to a database, it may contain an Order object that contains information about the order (when it was placed, the total amount, etc) and an array of LineItem objects that represent each item in the order and the quantity ordered. In a relational database the line items must be in a separate table. The order table would contain the information corresponding to the Order object and a line_item table would contain the information associated with each LineItem object. JPA will do the heavy lifting behind the scenes to make this conversion happen, but the programmer must supply the information about the ways the different objects relate to each other.

7.1.2 Entity Classes

The basic element of JPA is an entity class. Entity classes make up the model in the MVC design pattern. Essentially an entity is a plain old Java object (POJO) that holds data for the purposes of saving that data in a database. An entity class has the following characteristics:

• The class is annotated with the @Entity annotation so that the Enterprise container will recognize it as an entity class.

• The class's member variables should not be public. Access to the variables should be through accessor (getter) and mutator (setter) methods.

• The class should have a no-argument constructor. It may have other constructors, but the no-argument constructor must exist.

• The member variables that will be persisted to a database should be primitive types , serializable classes (such as java.util.Date), or classes that implement the Collection interface (like Lists or Sets).

List 7.1 shows a simple entity class;

@Entity

public class Customer {

@Id

@GeneratedValue(strategy=GenerationType.AUTO)

protected String ssn;

@Column(name=”full_name”)

protected String name;

}

A simple entity class

As you can see from list 7.1 an entity class is a simple POJO class decorated with some annotations. These annotations are the magic that make all of the object-relational mapping work. Entity classes should have the @Entity annotation applied so that Java can tell that it is supposed to be an entity class instead of a simple non-persistent class. The ssn member variable has two annotations, @Id and @GeneratedValue. Each entity must have an @Id annotation. This tells JPA that the data element is the primary key in the database. Without a primary key JPA would have no way to distinguish one record from another in the database. The @GeneratedValue annotation is optional and we will look at it further in the next section.

The name member variable is annotated with @Column. This is an optional annotation that tells JPA that the database column name for this variable is full_name. If this annotation was not present JPA would look for a column with the same name as the variable. Because the ssn String has no @Column annotation JPA will look for a column named “ssn” to store the contents of the name String.

The entity class in listing 7.1 uses persistent fields. An entity class may use either persistent fields or persistent properties depending on where the annotations are placed. If the annotations are applied to the member variables then the entity will use persistent fields. If persistent properties are used, then the member variable's accessor (getter) method would be annotated. If persistent properties are used then JPA will use the getter and setter methods when persisting the object to the database. If persistent fields are used then it will access the fields directly. An entity class may use either persistent fields or properties, but cannot mix the two in the same class (or class hierarchy if there is any inheritance is involved). It is often convenient to use persistent fields because the corresponding getter and setting methods do not need to be written. The convenience comes at a price, however, since accessing the fields directly means giving up some of the benefits of encapsulating the fields in an object-oriented manner such as validating the data in the setter methods. To offset the inconvenience, NetBeans provides a quick way to generate getter and setter methods which we will see later.

If persistent properties are used, the getter and setter methods for each persistent property must conform to the JavaBeans convention, including:

• Accessor methods are in the form of type getXyz() for variable xyz

• Mutator methods are in the form of setXyz(type xyz) for variable xyz

• Boolean accessor methods may be named isXyz() instead of getXyz()

The annotations for persistent properties must be applied to the getter methods. Annotations applied to setter methods will be ignored.

Composite Key:

A primary key in a database table need not be a single column. Likewise an entity's Id doesn't have to be a single variable. Consider the simple class that keeps track of software installed on a company's workstations in Listing 7.2. The class has fields for the software name, version, and the number of licenses the company owns. Using the name field as an entity Id may cause problems since there may be different versions of the same software installed on different computers. The software name and version must be used together to uniquely identify a particular Software object. Using multiple @Id annotations would be problematic sine we need a clearly defined way to determine if two Id's are the same. We can use a primary key class to represent both values in one tidy package with the @IdClass annotation. The primary key class will include the logic to compare itself against another primary key class to determine if they are the same by means of the equals(Object otherObject) method.

public class Software {

String name;

String version;

int licenses;

}

A simple entity representing installed software licenses

A primary key class must follow some simple conventions:

• It must have a no-argument constructor.

• It must be declared public and the fields or properties declared public or protected.

• It must implement the Serializable interface.

• It must implement an equals(Object otherObject) method and the hashCode() method.

• The names of the fields or properties must match the names in the entity it represents exactly.

Listing 7.3 shows the SoftwareId class and the corresponding Software entity class. The member variables have been made public and accessed directly to keep the listing short although in a real implementation the Id class would use getter and setter methods.

public class SoftwareId implements Serializable {

public SoftwareId() {

}

public boolean equals(Object o) {

if(o instanceof SoftwareId) {

return name.equals(o.name) && version.equals(o.version);

}

else {

return false;

}

public int hashCode() {

return super.hashCode();

}

public String name;

public String version;

}

@Entity

@IdClass(SoftwareId.class)

public class Software {

@Id

public String name;

@Id

public String version;

public int licenses;

}

Software entity and its IdClass SoftwareId

7.2 Entity Relationships

It would be difficult to model an entire application around a single entity class. A non-trivial application will have several entity classes making up the data model. These entities usually have some sort of relationship to each other. Take for example an application for a university that keeps track of a student's GPA. The data model would include a Students who are assigned Grades for taking Courses. In addition a GPA is maintained for each Student and stored separately. The Java objects represent these relationships by maintaining references to other objects to which they are related. The Student class would have an array (or a List or other Collection in an entity class) of Grade objects. Each Grade object could in turn have a reference to the Student object that it is assigned to. So Student instance student1 would have a list of Grade objects accessible my means of the getter method student1.getGrades(). Each Grade in the list would have a grade.getStudent() method that would refer to the student who earned the grade. In order to tell the ORM provider how to store this relationship information in the database correctly and efficiently we must provide information about the multiplicity of these relationships.

7.2.1 Multiplicity

Multiplicity refers to the number of object instances that can participate in the relationship. The objects relate to each other in the following ways:

Each Student takes many Courses

Each Course has many Students enrolled in it

Each Grade is assigned to only one Student

Each Student may be assigned several Grades (from taking several courses)

Each Student has a single GPA

Each GPA belongs to a specific Student

Diagram showing the relationships between Course, GPA, Grade, and Student. The triangular arrows indicate that many of these entities participates in the relationship.

There are several different relationships here (see figure 7.1) which we will examine one at a time.

One To One

The Student and GPA objects participate in a one to one relationship. A single Student may have one (and only one) GPA. Likewise, a GPA may belong to only one student. Note that this does not mean that two students may not have the same value for their grade point average. It simply means that each Student object will hold its own unique instance of a GPA object, regardless of what value that object holds. A one to one relationship is signaled by annotating the appropriate field or property with the @OneToOne annotation.

One To Many

The Student object contains a List of Grade objects. This is a one to many relationship since one Student contains many Grades. Remember that in an entity class the many part must be a reference to a Java Collection (such as a List or Set of objects) of objects and not just a simple object reference. To declare a one to many relationship, annotate the Collection field or property with the @OneToMany annotation.

Many To One

The many to one relationship is the direct inverse of the one to many relationship. In our example each Grade has a reference to the Student it is assigned to, so the Student field or property in the Grade object would be annotated with the @ManyToOne annotation.

Many To Many

The Student and Course entities have a many to many relationship. That is, a Student may take many Courses and a Course may have many Students in it. To distinguish a many to many relationship from a one to many relationship the @ManyToMany annotation is used on the corresponding Collection field or property.

7.2.2 Direction and Ownership in Relationships

Relationships between entities may be unidirectional or bidirectional. A unidirectional relationship goes one way. An example would be a Student entity that has a reference to a GPA entity but the GPA entity does not have a corresponding Student reference. The distinction is important because it restricts the path you can take to get to any particular piece of data. A unidirectional relationship from Student to GPA mean that, given a particular Student you can find the GPA associated with it. If you have a particular GPA entity, however, you cannot find out which Student it belongs to without making the relationship bidirectional.

In practice what this means is that the Student entity has a reference to a GPA entity as one of its persistent fields or properties which has been annotated with the appropriate relationship annotation (@OneToOne in this example). To make the relationship bidirectional we must add a persistent Student entity to the GPA entity and tag it with the corresponding relationship annotation. For Student and GPA, both entities will have the @OneToOne annotation on the field or property representing the other entity.

Care must be taken when dealing with bidirectional many to one relationships, however. While a Student entity has a List of Grade entities marked as @OneToMany, the Grade entity will have a single Student entity field or property annotated with @ManyToOne. Because many to one is the inverse of one to many you must change the annotation when the direction changes. You can think of it from the point of view of the entity you are annotating. @OneToMany means one of this entity (the one you are adding the annotation to) to many of an outside entity. Likewise @ManyToOne means there will be many of this entity to one outside entity. The two fit together to represent a bidirectional relationship from each entity's point of view. Many to many bidirectional relationships are similar to one to one relationships in the sense that the same annotation is used on both entities participating in the relationship since the relationship appears the same from both sides.

When bidirectional relationships are used one of the entities must be specified as the owner. Ownership simply means that one of the entities is responsible for maintaining the relationship. There is no extra programming involved in maintaining the relationship, it is a matter of which of the tables in the relational database has the primary key and which one as the foreign key. In many to one relationships the many side is always the owning side (that is, the side with the @ManyToOne annotation). The one to many side cannot be the owning side in JPA. For one to one and many to many relationships either side may be the owning side.

To make clear which side is the owning side of a relationship we add some additional parameters to the side that does not own the relationship. The entity which does not own the relationship will have the mappedBy=”XXX” property set in the relationship annotation where XXX is the name of the field or property in the other entity that refers to this one. All of the relationship annotation support the mappedBy property except @OneToMany, since it cannot be the owning side of a relationship. In addition, the @OneToOne and @ManyToOne annotations have a property named optional which defaults to “true.” If this is set to false then the entity that is annotated must exist. That is to say that the entity reference cannot be null in the object. For example, our annotation in the GPA entity which refers to the Student entity would have the optional parameter set to false. This mean that in order to have a GPA entity we must also have a Student entity for it to refer to. It would not make much sense to have GPA records that did not belong to any student.

7.3 Storing and Manipulating Entities

So far we've looked at entities, how they are annotated, and how they relate to each other. Now we will discuss how to make use of them with the EntityManager interface.

7.3.1 Persistence Context and EntityManager

The persistence context is the collection of managed entities in a particular data store. The persistence context is manipulated by means of the EntityManager interface. Unlike session beans, entities are not directly managed by the enterprise container. They are managed by the persistence context (which does not require an enterprise container). The EntityManager is the the means by which an application accesses the persistence context.

Entity Life Cycle

Entities exist in one of four distinct states: detached, managed, new, or removed (see figure 7.2). New entities are just that – new. When you create a new instance of an entity class you have an entity in the new state. Once an entity has become managed it is represented in the data store and is associated with a persistence context. An entity becomes managed when it is persisted to the data store using the EntityManager (which we will see shortly). An entity may become detached if it is serialized or if the EntityManager it is attached to goes out of scope (at the end of a method if the EntityManager instance is local the method, for example). Finally an entity enters the removed state when it has been removed from the data store by the EntityManager. Although the record is gone from the data store the entity itself may still be around in the application until it goes out of scope.

In an enterprise application the EntityManager is obtained by injecting it into a managed component (like a session bean) through the @PersistenceContext annotation. This is typically all that is required to use entities in a session bean. Using JPA in a servlet typically requires a little more care, however. Servlets may also have an EntityManager injected in this manner, but it usually is not a good idea to do so because the EntityManger is not thread safe. Thread safety is an important consideration with servlets since a single servlet instance may handle all incoming requests, so instance variables may be shared. When using JPA with servlets it is better practice to inject the thread safe EntityManagerFactory using the @PersistenceUnit annotation and use it to obtain an EntityManager through its createEntityManager() method.

All EntityManager operations must take place within a transaction. A transaction is a set of individual actions that must be performed as a single unit. Imagine an application that keeps track of payments for a bank. When a customer pays with a debit card, two things have to happen. The customer's account must be debited by the amount of the purchase and the seller's account must be credited by the same amount. Both of these can be handled by entity beans representing the different accounts. If the bank's data center has a power outage between the time the customer's account entity is saved to the database and the time the seller's account entity is saved, then the money is effectively lost. It has been subtracted from the customer's account but was never added to the seller's account. This is certainly sub-optimal and leads to angry customers. Transactions enforce an all-or-nothing approach to all of the entity operations they contain. If one part of the transaction fails, then all parts have failed and must be undone so that the database is not left in an inconsistent state. After all an inconsistent database is arguably worse than no database at all.

In a session bean the container takes care of all of the transaction details behind the scenes automatically as part of the Java Transaction Architecture (JTA). When an EntityManager is injected into a session bean the container has already made sure that it is associated with a transaction. In a servlet, controlling the transaction requires a little more work involving a UserTransaction object. A UserTransaction object may also be injected into the servlet with the @Resource annotation to provide transaction control. Beginning and ending the transaction is as simple as surrounding the EntityManager method calls with the UserTransaction's begin() and commit() methods. We will show an example of this usage in section 7.4.

7.3.2 Manipulating Entities

Relational databases support four basic operations: create, read, update, and delete (often abbreviated CRUD). It is not surprising that the EntityManager offers methods corresponding to each of these four operations.

For creating new records in the database the void EntityManager.persist(Object entity) method. This method will take a new entity and persist it to the database, perforiming the JPA analog of a Create database operation. The entity that was persisted will enter the managed state. Unless the entity's Id field or property is automatically generated there may be the possibility of trying to create a record with the same Id as an existing record. In order to avoid this you should make sure that the Id field or property does not already exist in the database (see section 7.3.3).

The T EntityManager.find(Class entityClass, Object primaryKey) method corresponds to a database's Read operation. When passed in the class of the entity you need and its Id value as parameters, the find method will retrieve the entity from the database and return it. The returned entity will be in the managed state.

T EntityManager.merge(T entity) performs the JPA version of the database's Update operation. The values held in the entity will be merged with the existing record in the database. When dealing with a managed entity there are, at any given time, two versions of the entity – one that has been persisted to the database's data store, and one that resides in memory in the Java application. This method will effectively synchronize the two by making the version in the database match the version represented by the Java object. If this is not the desired result and the Java object must instead be made to match the database version, then a different method is needed. The void EntityManager.refresh(Object entity) method will synchronize the two versions in the opposite direction, making the Java object match the version in the database.

The final database operation, Delete, is performed by the void EntityManager.remove(Object entity) method. This method will remove the record that corresponds to the entity from the database and place the entity in the removed state.

The relationship annotations discussed in section 7.2.1 support the optional named parameter cascade. This parameter specifies whether persistence operations such as saving to or deleting from the database follow the relationship links between entities, similar to the way cascading works in relational databases. For example, if we have a Grade entity that belongs to a Student entity and both are in the new state, one might expect that persisting the Student entity would also save the Grade entity to the database. By default, this is not the case. If this is the desired behavior, the cascade parameter may be set to one of the following values:

CascadeType.ALL – all operations (persist, merge, refresh, and remove) follow the relationship.

CascadeType.MERGE – only merge operations are cascaded to the referenced entities.

CascadeType.PERSIST – only persist oerations are cascaded to referenced entities.

CascadeType.REFRESH – only the refresh operation is cascaded to the referenced entities.

CascadeType.REMOVE – only the remove oeration is cascaded to referenced entities.

Cascading can be helpful some situations, keeping the developer from having to call EntityManager methods on multiple related entities when new entities are persisted or old entities removed. It should be used judiciously, however. If relationships are set to cascade remove operations it is possible to accidentally remove more than you intend. For example, if the Grade and Student relationship is bidirectional and set to cascade remove operations, then removing a Grade could remove the Student it is assigned to as well.

7.3.3 Finding Entities

While performing CRUD operations makes the EntityManager a very useful tool, there is one more method that makes it invaluable. The Query EntityManager.createQuery(String qlString) method plays and important role in retrieving data. It allows a query to be sent to the database and a Query object which contains the results of the query. The reason this is so useful is because an Id value is required to retrieve an entity from the database using the EntityManager's find method. Even if you have a person's name, birthdate, and address you will have a difficult time retrieving the entity instance associated with that person without the Id. To fnd the entity's Id or a set of possible Id's you would create a query and retrieve the Id from the results (see Listing 7.4).

Query q = EntityManager.createQuery(“select p from person p where p.name = 'John Doe' and p.birthdate = '1977-08-21'”);

Person p = q.getSingleResult();

String ssn = p.getSSN();

A query created to find an entity's Id when other information is known

You may have noticed that the syntax is similar to SQL. This is no coincidence. It is not SQL, however, but a special language designed for retrieving entities from a database called the Java Persistence Query Language (JPQL). EntityManager's createQuery method also has a close relative called createNativeQuery which takes a SQL statement to send to the database. This may be simpler for developers who are familiar with SQL and who know what kind of database their entities will reside in, but has the potential to reduce the portability of the entities since some databases may have slightly different syntax or vendor-specific features that are unsupported elsewhere.

The major difference between JPQL and SQL is that SQL is designed to retrieve specific rows from a table made up of columns specified in the query. For example, selecting the last name and first name of all people in Oklahoma might look like this: “select last_name, first_name from people where state = 'Oklahoma'”. The columns that are returned are specified in the select clause, the table to look is specified in the from clause, and the conditions to match on appear in the where clause. JPQL on the other hand is designed to operate on entities. The same query in JPQL might be written as: “select p from person p where p.state = 'Oklahoma'”. The columns aren't specified in the select clause because entities or entity properties are returned instead of certain specified columns. Here p refers to person (the entity which shows up in the from clause). In essence the query is saying “Look in the person storage for a person entity that has its state member set to the value 'Oklahoma'.”

The createQuery method returns a Query object. The Query object has several methods used to retrieve the results. getResultsList() will return a List containing the resulting entities from the database. getSingleResult() will return a single entity. Once you have retrieved the entity you are looking for you may manipulate it using the EntityManager's CRUD methods because you now know its unique Id.

7.4 Your First JPA Application

Now that we have covered the basics of the Java Persistence API we will construct a simple application to try it out. We will create a simple guest book application that records the first and last name of visitors who visit the website.

1. Open the NetBeans IDE

2. Choose File → New Project

3. Choose Java Web from the Categories menu on the left and choose Web Application from the Projects menu on the right and click “Next”

4. Name the project “MyFirstJPA” in the Project Name box and click “Next”

5. Choose GlassFish V2 as the Server and click “Finish” to create the project

6. Open the automatically generated index.jsp that was created in the project and replace the default HTML with the following:

JPA Guest Book

,

Sign the Guest Book

First Name:

Last Name:

7. In order to save our objects to the database, we need to make sure we have a database to save them in.

1. Click on the Services pane in the upper-left of the NetBeans IDE and expand the Databases node.

2. Right-click the Java DB service and click the “Start Server” menu item. This will start the Java DB engine that comes bundled with NetBeans.

3. Right-click the Java DB service again and choose the “Create Database” menu item.

4. In the Create Java DB Database dialog, enter myfirstjpa as the database name and enter app for both the user name and password fields.

You should now see a new database named myfirstjpa in the database list.

8. Right-click on the MyFirstJPA project node and choose New → Entity Class from the context menu.

If Entity Class is not one of the available options you may add it by choosing Other from the context menu. Choose Persistence from the Categories menu on the left and Entity Class from the File Types menu on the right and click “Finish”

9. Enter Guest as the Class Name and myfirstjpa.entities as the Package. You will also see a warning that a Persistence Unit must be created. The persistence unit defines some details for JPA such as the data source for the database. Click the “Create Persistence Unit” button to create the persistence unit.

10. In the Create Persistence Unit dialog, name the new persistence unit MyFirstJPAPU and set the persistence provider to TopLink(default) and leave the Table Generation Strategy on “Create.”

11. In the Data Source drop-down menu, choose the New Data Source option to create a new data source.

12. In the Create Data Source dialog enter jdbc/myfirstjpa as the JNDI Name and choose the myfirstjpa database connection that we set up in step 7. Click “OK” to create the data source. Click “OK” again to finish the creation of the persistence unit.

13. Click “Finish” to complete the creation of the Guest entity.

14. You will notice that the myfirstjpa.entities package has been created along with the Guest entity class. Opening the entity class in the editor will show that NetBeans has already put much of the structure in place for you, including an auto-generating Id field.

15. Add two additional member variables beneath the id field:

public String firstName;

public String lastName;

16. To auto-generate getter and setter methods for the new String variables, right-click on Guest.java and choose Refactor → Encapsulate Fields from the context menu.

Check the boxes in both the Create Getter and Create Setter columns for the lastName and firstName variables. Click the “Refactor” to have NetBeans automatically generate the getter and setter methods.

17. Right-click on the MyFirstJPA project node and choose New → Servlet from the context menu.

18. Enter GuestBook as the Class Name and myfirstjpa.servlets as the Package and click “Finish” to create the Servlet.

19. Open GuestBook.java in the editor window. You will see the famework for a servlet.

20. Add the following lines to the class definition to inject a UserTransaction object into the class:

@Resource

UserTransaction utx;

The @Resource annotation and the UserTransaction class name both appear with red lines beneath them, indicating that NetBeans cannot find the class definitions. Click on the light-bulb icon in the left margin next to the @Resource annotation and choose “Add import for javax.annotation.Resource” from the menu. This will automatically add the appropriate import statement. Repeat the procedure for the light-bulb icon in the margin next to the UserTransaction class name. The UserTransaction object will allow the servlet access to a transaction for use with the Guest entity.

21. Add the following lines to the class definition to inject an EntityManagerFactory object into the class:

@PersistenceUnit

EntityManagerFactory emf;

Follow the procedure in step 20 to automatically import the appropriate class definitions.

22. Replace the auto-generated contents of the servlet's processRequest method so that the method looks like this:

protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

response.setContentType("text/html;charset=UTF-8");

try {

utx.begin();

EntityManager em = emf.createEntityManager();

String action = request.getParameter("action");

if("add".equals(action)) {

Guest g = new Guest();

g.setFirstName(request.getParameter("firstname"));

g.setLastName(request.getParameter("lastname"));

em.persist(g);

}

List guestList = em.createQuery("select g from Guest g").getResultList();

request.setAttribute("guestList", guestList);

mit();

}

catch(Exception e) {

e.printStackTrace();

try {

utx.rollback();

} catch(Exception ex) {

ex.printStackTrace();

}

} finally {

RequestDispatcher rd = this.getServletContext().getRequestDispatcher("/index.jsp");

rd.forward(request, response);

}

}

23. Click the run button to deploy the project.

24. The index page will open in a new web browser and the web form will appear. Entering a first name and last name and clicking the “Sign Guest Book” button will result in the information being saved to the database by means of the Guest entity. Enter a few names to test.

25. Click on the Services pane in the upper left corner of the NetBeans IDE and expand the Databases node. Right-click on the database we set up in step 7 and choose “Connect” from the context menu.

26. Right-click on the database again now that you are connected and choose “Execute Command” from the context menu.

27. In the SQL Command editor that opens, enter the following SQL query:

select * from guest;

Click the “Run SQL” button at the top of the editor pane to execute the SQL statement. You will see the database rows containing the entities saved by the servlet.

The NetBeans IDE makes working with entities very simple. In our first example most of our time was spent setting up the environment for the entities to live in, such as the database connection , the servlet, and the JSP page containing the form.

................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download