Category: JEE 5.0


Non-obtrusiveness, responsiveness and high interactivity are the areas where desktop applications still have an edge over the web-applications. The intelligent use of JavaScript can create highly interactive web-sites. However, responsiveness and non-obtrusiveness would still be a distant dream. The responsiveness can be achieved by careful implementation at server-side by using technology such as J2EE that uses threading mechanism to service requests. But, to achieve non-obtrusiveness, a component is required that can provide asynchronous means of communication so that complete re-rendering of a page during the response phase can be bypassed. That is where AJAX comes into picture. AJAX provides asynchronous communication service through JavaScript and XML. Thus a good combination can be formed by using AJAX at client-side and Servlet at server-side providing non-obtrusive, responsive and highly interactive web experience. In this discussion, I would be focusing on utilizing such a winning combination. The first section would be detailing the steps required for setting up of application for utilizing AJAX along with servlet. In second and the last section I would be developing a registration module that would use AJAX to check the availability of the username. That’s what’s in store for this discussion.

AJAX and Servelets- The Steps for Implementation:

AJAX or Ajax is really not a technology in itself but it is a combination of existing technologies. These form the basis of the asynchronous communication, XML and HTML manipulation. So lets have look at these components:

1. XML

2. XMLHttpRequest (JavaScript)

3. HTML/XHTML with CSS

4. Server-side component.

The steps to implement AJAX cover these entire components. The JavaScript communicates with the server using XMLHttpRequest, receives response in the form of XML from the server side component which is used by the JavaScript to manipulate the HTML to present data to the user. That is the complete cycle of AJAX request-response cycle in nut-shell. The implementation that gives raise to the aforementioned cycle constitutes the following steps:

1. Setting up the XMLHttpRequest

2. Calling the server-side component

3. Registering and implementing call-back handler and at the server side

4. Generate the XML response.

How the four components fits with the implementation steps is detailed below.

1. Setting up the XMLHttpRequest:

The very first step of AJAX setup comes in the form of instantiating XMLHttpRequest. It exists in two varieties- first as an ActiveX control and second as a JavaScript object. The Internet Explorer considers it as an ActiveX while Mozilla, Firefox and Opera consider it as a JavaScript. So to set up XMLHttpRequest the browser type has to be checked. The best way to check the type is to determine whether the client browser supports ActiveX or not. If ActiveX is supported then instantiate using CreateObject() method otherwise use XMLHttpRequest’s constructor to do the same. In code, it would be:

var xmlHttp;

if(window.ActiveXObject)

{

xmlHttp=new ActiveXObject(“Microsoft.XMLHTTP”);

}

else if(window.XMLHttpRequest)

{

xmlHttp=new XMLHttpRequest();

}

Instead of directly using else part, the check can be done on the browser supporting XMLHttpRequest as an object or not. To instantiate the XMLHttpRequest object as an ActiveX, then the object name which in this case is Microsoft.XMLHTTP, has to be passed to the CreateObject method. To instantiate it using the constructor, new XMLHttpRequest() has to be used. That completes the setting up step.

2. Calling Server-Side Component:

To make a call to the server-side component (in this case servlets) the methods of XMLHttpRequest instance have to be used. Which method to be used depends on the type of method to be used. following are the methods:

i. setRequestHeader

ii. open

iii.send

The first method comes into picture when the method of HTTP request has to be POST. The parameters taken by the second and third methods change according to the method used.

i. setRequestHeader:

It sets the value of the header given as parameter. This method takes two parameters-the name of the request header, the value of the header. This method comes into picture when POST method is used. For example, if POST has to be used, the statement would be:

xmlHttp.setRequestHeader(“Content-Type”, “application/x-www-form-

urlencoded; charset=UTF-8″);

The first parameter sets the name of the header as Content-Type and its value as application/x-www-form-urlencoded. Also its sets the character set of the content as UTF-8. But it is important to call open before setting the header.

ii. open:

This is the method that actually sets up the communication with the server. The URL corresponding to the servlet is given as the second of the parameters. The first parameter is the type of the method to communicate with the server. It can be either GET or POST or PUT. If GET is used, the data sent as query string by appending it to the URL i.e. the first parameter. The third parameter, which takes a Boolean value decides whether the communication would be synchronous or asynchronous. A true value makes the communication asynchronous whereas a false value makes the communication synchronous. The last two optional parameters are required only when the server requires authentication. For example, to call a servlet having a URL http://localhost:81/SCM/register having asynchronous communication, the statement would be:

xmlHttp.open(“GET”,”http://localhost:81/SCM/register?user=”+user, true);

Here the value to be sent to the server is passed as a query string appended to the URL.

iii. send:

This sends the data to the server when the method is POST. If it is GET, then

null is send to the server. In case of POST, a string of name-value pair is set as its parameter. For example, to send user name and password to the server and the method is POST, the statements would be:

var params=”user=”+user+”&pass=”+pass;

xmlHttp.send(params)

That completes setting up the XMLHttpRequest.

3. Registering and implementing call-back handler:

There needs to be a handler that can be invoked when the response arrives. It is the callback handler. A callback handler is simply a function that is registered with the system and that is invoked by the system when the event for which it is registered. So in this case the event is arrival of data along with the response. To handle this event, a function has to be registered with the XMLHttpRequest which is done by the onreadystatechange property of XMLHttpRequest. So to register a function named handleStateChange(), the statement would be:

xmlHttp.onreadystatechange=handleStateChange;

The next step is to implement the handler. The basic functionalities that a handler should implement are retrieving data from XML response sent from the servlet and manipulating the current page on the browser according to the data received from the server. For example, to display the result coming from the server on the page, the code would be:

function handleStateChange()

{

if(xmlHttp.readyState==4)

{

if(xmlHttp.status==200)

{

document.getElementById(“results”).innerHTML=xmlHttp.responseText;

}

else

{

alert(“Error loading page\n”+ xmlHttp.status +”:”+ xmlHttp.statusText);

}

}

}

Here the element having the id results is a <div> tag. So whatever be the data coming from the server is displayed as child nodes of the results. The three properties that are being used here are-readyState, status and responseText. The readyState specifies whether data load operation is successful or not. Any value except 4 indicates that data is not yet available. Even then if the data contains a ‘file not found message’, then also the next part wouldn’t work as required. Hence, it is always better to check the status. The data is usable only if the status is 200. The next part is to extract the data and use it. The XMLHttpRequest instance has two properties-responseText and responseXML to extract data from the response. If data is in the form of text then responseTest can be used otherwise responseXML can be used.

The only piece of the puzzle is the server-side part. That’s what coming up.

4. Generate the XML response:

Whatever be the server-side technology, the implementation has to generate XML. In this case the technology is servlet. To generate the response the three things have to be done- first set the content type to text/xml, secondly get a writer object and then set the XML into the response using the writer object. The code would be something like:

response.setContentType(“text/xml”);

response.getWriter().write(“<valid>true</valid>”);

where response is an object of HttpServletResponse. That’s it. In the next section I would be putting it all together to develop a registration module that would check the availability of the user id.

AJAX and Servlets- In the Real World:

The module to be developed has to check the availability of a user id. Why use AJAX here? The answer is that if the user id is already taken, then it is always better to tell the user as soon as possible. By using AJAX this can be done once the user id has been entered. The AJAX would come into picture when the user id is filled and the user moves to next field. This module contain three major components:

1. ValidateAvail.js – JavaScript file containing all the client-side AJAX functions

2. Register.html – The registration page

3. CheckAvail.java – Servlet that does the server-side processing

So here is the code.

First lets have a look at the ValidateAvail.js. The first thing to do is setting up the XMLHttpRequest. Its being done by the following function:

var xmlHttp;// global instance of XMLHttpRequest

function createXmlHttpRequest()

{

if(window.ActiveXObject)

{

xmlHttp=new ActiveXObject(“Microsoft.XMLHTTP”);

}

else if(window.XMLHttpRequest)

{

xmlHttp=new XMLHttpRequest();

}

}

Next the function that sets up the communication with the server

function startRequest()

{

createXmlHttpRequest();

var u1=document.f1.user.value;

xmlHttp.open(“GET”,”http://localhost:8080/SCM/checkAvail?user=”+u1

,true)

xmlHttp.onreadystatechange=handleStateChange;

xmlHttp.send(null);

}

This function also registers the callback handler which is handleStateChange. Next is the code for the handler.

function handleStateChange()

{

if(xmlHttp.readyState==4)

{

if(xmlHttp.status==200)

{

var message =

xmlHttp.responseXML

.getElementsByTagName(“valid”)[0]

.childNodes[0].nodeValue;

document.getElementById(“results”).innerHTML=message;

}

else

{

alert(“Error loading page\n”+ xmlHttp.status +”:”+

xmlHttp.statusText);

}

}

}

After checking the readyState and the status, the data is extracted from the response using JavaScript XML parsing APIs. The data is then passed on to the HTML page using DOM API. Now lets have a look at the HTML page. Only the relevant portion is being shown.

<tr>

<td width=”36%”>Userid</td>

<td width=”33%”>

<input type=”text” name=”user” onBlur=” startRequest();”/>

</td>

<td width=”31%” id=”results”>&nbsp;</td>

</tr>

The startRequest() function is called on the Blur event. Thus starting the AJAX process.

The next in line is the servlet code. Here it is:

package someorg;

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

import java.util.*;

public class CheckAvail extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws IOException, ServletException {

UserOp userOp=new UserOp();//business layer class.

//implementation not shown for brevity

//get the userId

String targetId = request.getParameter(“user”);

//check the id. If it is not existing already then return true else false

if ((targetId != null) && !userOp.containsKey(targetId.trim())) {

response.setContentType(“text/xml”);

response.setHeader(“Cache-Control”, “no-cache”);

response.getWriter().write(“<valid>true</valid>”);

} else {

response.setContentType(“text/xml”);

response.setHeader(“Cache-Control”, “no-cache”);

response.getWriter().write(“<valid>false</valid>”);

}

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws IOException, ServletException {

doGet(request, response);

}

}

}

The servlet retrieves the value of parameter and then checks whether the user id is already existing in the database or not using the business layer class. If it does not exists, then the XML out put contains true as the node value of the node <valid> otherwise it would contain the value false. That’s it. This brings us to the end of this discussion. Using AJAX with servlet is just one of the many option available to a JEE developer. In the future I would be discussing other options including Struts and JSF. Till then…

Realms- Securing the J2EE Applications using Container Services

In the world of web applications, security is paramount, more so when the platform is J2EE. A J2EE application consists of different components such as Web Component, Business Logic components and so on. Each of these components execute in their own containers. So, in essence, each component can be provided security by the container in two ways:

  1. Declarative Security

Declarative security is based on Realms, Roles, Users and Groups (more on that later).

  1. Programmatic Security

In Programmatic security, the security is provided through the code embedded in the application itself. Java Authentication and Authorization Services or JAAS belongs to this category.

Securing a web application (for that matter any application) has always two broad phases- Authentication and Authorization. In authentication one validates the credentials of the user. Login procedure is a part of authentication. The next step is setting up and controlling the access rights of the successfully authenticated user. This complete phase comes under Authorization. In authorization a user’s right to access the resources provided by the application is controlled.

In a J2EE application, both of these are managed using Declarative Security. The security service uses the verified credentials supplied at the authentication to control the access to the resources within the application. Hence when authorization comes into picture authentication must also be addressed. Hence here both the phases and the role of Realms in these phases will be discussed here.

  1. Realms, Roles and Users:

Realms, roles and users- these words crop up every time security is discussed in the context of J2EE security. So what are these? Let’s have a detailed view of the trinity of security.

    1. Realms:

A realm defines the boundary of an application. Whatever comes within this boundary is secure. Technically, a realm is a policy that defines how a user is authenticated in a secured domain. This policy contains the list of users and the mechanism to authenticate them. This is similar to Access Control List and authentication mechanism deployed by Windows NT based systems and/or UNIX based systems.

    1. User/Principal:

A Principal is user within the security policy domain. The principal is also known as user within the realm. The username of the user that he/she uses to login and that user’s principal name need not be similar. That’s what the J2EE specification tells but almost all the J2EE implementations utilize the username itself as the principal name.

    1. Roles:

Roles are the references to the actual roles described within the application. The developer uses this reference to map the user to a role. Each user has a role reference mapped into his/her principal name. The reference in turn is mapped onto the actual role within the application. Common role references are Administrator, role1 etc.

  1. Common Implementations of Realms:

As mentioned J2EE application starts using the container’s security services from the time of user’s authentication. Hence the chief implementations of realms also are based on how or where the principals and the related realms are stored. Whenever the container needs to lookup the names and the roles, it uses these ‘storages’. The users and their roles can be stored in three major ways which are xml files, relational databases and directory of LDAP based directory server. So the implementations are:

    1. Memory Realm

    2. JDBC Realm

    3. JNDI Realm

  1. Memory Realm:

Memory realm is based on xml files. All the user names, passwords and their respective roles are stored in a xml file. Whenever the container starts up, it parses this xml file and loads the information into the memory. So until the server is stopped, the complete information is stored within the memory space of the container. Whenever authentication and successive authorization has to be done the supplied credentials (from here I will be using the term credentials for the information supplied by the user) are checked against the in-memory information. The upside of this implementation is that it is easier to setup and use. The downside is that newer information added to the xml file won’t be reflected till the container is restarted. So it is not a good choice for production purposes.

  1. JDBC Realm:

In JDBC realm, the credentials of a user are stored in a relational database table. The container uses JDBC driver to access the information. The major difference between memory realm and JDBC realm is the way in which the credentials are stored. The JDBC realm, as already said, uses tables. The default (also the commonly used) names of these tables are Users and Roles. Whenever a new user is registered, the application or the web administrator has to enter the credentials into the Users table and the corresponding role has to be entered into the Roles table. The container, whenever required uses the information available in the tables to authenticate as well authorize a particular user. The advantage of this implementation is that new information can be entered and used without restarting the server. Also data becomes more secure as the data is not stored in plain text files. Hence for most of the production purposes it is recommended as well as used.

  1. JNDI Realms:

JNDI Realm uses LDAP services provided by a JNDI provider. This is the most complex and the most extensive container based security implementation that any vendor provides. An LDAP directory server contains credentials of the user. The credentials are kept as directory entries in the server. These entries are accessed via the JNDI services within the container. By default, the authentication is done by Bind mode. In this mode, the realm binds the user to the DN entry of the LDAP server using the username and password provided by the user. A user is said to be authenticated if this simple bind succeeds. The passwords of the registered users are not saved in plain text. Instead digest of these passwords are store. Digesting is a form of encryption. So security fears can be dispelled. Again, as in the case of JDBC realms, the entry of registered users is left to the application or web administrator. Though JDBC and JNDI are almost similar, yet the extensive choices provided by the JNDI realm gives it an upper hand.

  1. Implementation of Realm -An example:

So much for the theory, lets see a real world example. As I have already mentioned, in the Declarative security, the constraints are declared in the deployment descriptor i.e. web.xml. So the only part one has to deal with as a web developer is deployment descriptor.

The example that I am citing here deals with a java based Content Management System (CMS). The CMS (lets call it JCMS) has certain resources such as video files, documents etc that can be accessed only by authorized users only. To be more precise we have secure the folders containing the resources. Let’s see how to do it.

Once all the mappings concerning the web application are done, the security declarations and mappings come into picture. The mapping for securing the application resources comes between the following:

<web-app>

:

:

<security-constraint>

:

:

:

</security-constraint>

:

:

</web-app>

In other words to the security mapping <security-constraint> acts as parent node. Then the resources that have to be secured must be declared. Like servlet mappings it can be done for each resource separately or all the resources can be brought under the same declaration.

<web-app>

:

:

<security-constraint>

<web-resource-collection>

:

:

</web-resource-collection>

</security-constraint>

:

:

</web-app>

The <web-resource-collection> encapsulates the various resources that has to be secured. The next step is to give the name to the resource realm and then provide the url that would be used to access the resources.

<web-app>

:

:

<security-constraint>

<web-resource-collection>

<web-resource-name>Protected Area</web-resource-name>

<!– Define the context-relative URL(s) to be protected –>

<url-pattern>/secured/resources/*</url-pattern>

:

:

</web-resource-collection>

</security-constraint>

:

:

</web-app>

Then, tell the container, what are the HTTP methods, that would be used to access the resources. If the methods are listed, then only those methods would be protected.

<web-app>

:

:

<security-constraint>

<web-resource-collection>

<web-resource-name>Protected Area</web-resource-name>

<!– Define the context-relative URL(s) to be protected –>

<url-pattern>/secured/resources/*</url-pattern>

<http-method>DELETE</http-method>

<http-method>GET</http-method>

<http-method>POST</http-method>

<http-method>PUT</http-method>

</web-resource-collection>

:

:

</security-constraint>

:

:

</web-app>

Here we are telling the container that we want to authenticate all DELETE, GET,POST,PUT methods. So whenever any one of these methods are used in request, then container fires up the authentication process. But there are five types of authentication ( Form based and Basic are two of the most commonly used. How to tell the container which one to use? But before that the container needs to be told the authentic users for this resource. This is done a follows:

<web-app>

:

:

<security-constraint>

<web-resource-collection>

<web-resource-name>Protected Area</web-resource-name>

<!– Define the context-relative URL(s) to be protected –>

<url-pattern>/secured/resources/*</url-pattern>

<http-method>DELETE</http-method>

<http-method>GET</http-method>

<http-method>POST</http-method>

<http-method>PUT</http-method>

</web-resource-collection>

<auth-constraint>

<!– Anyone with one of the listed roles may access this area –>

<role-name>raj</role-name>

<role-name>admin</role-name>

</auth-constraint>

</security-constraint>

:

:

</web-app>

Once the user list is given, then the part comes where the type of authentication has to be provided.

<web-app>

<security-constraint>

<web-resource-collection>

<web-resource-name>Protected Area</web-resource-name>

<!– Define the context-relative URL(s) to be protected –>

<url-pattern>/secured/resources/*</url-pattern>

<http-method>DELETE</http-method>

<http-method>GET</http-method>

<http-method>POST</http-method>

<http-method>PUT</http-method>

</web-resource-collection>

<auth-constraint>

<!– Anyone with one of the listed roles may access this area –>

<role-name>raj</role-name>

<role-name>admin</role-name>

</auth-constraint>

</security-constraint>

<login-config>

<auth-method>BASIC</auth-method>

<realm-name>Example Basic Authentication Area</realm-name>

</login-config>

:

:

</web-app>

The <login-config> is the place where the type of authentication and the realm to be authenticated. Here we are using BASIC authentication that means whenever anyone tries to access the secured resources the container pops up the standard window dialog demanding the user name and password.

So we have secured our application without even writing a line of java code. Easy… isn’t it?

Where should one go from here? The next logical step is making the application more secure by using JAAS. How to do it … it’s for another time.

Welcome to the round two of Active Record v/s Rails. This round is based upon implementation of ORM classes. Lets start with Hibernate. The steps to implement ORM class in Hibernate are:

  1. Name the class (preferable) according to the table. For example, if table is named Employee, then the class is also named Employee. This is preferable but optional.
  2. Next declare the instance variable corresponding to the attributes of the table with which class is to be mapped. For example, if the Employee table has an attribute named Name, then the class will have an instance variable named Name. Its data-type will be the Java equivalent of SQL type. If Name attribute is varchar, the name instance variable will be String.
  3. Last step is to implement getters and setters for the instance variables.

Next let us see how to do this with Active Record
  1. Name the class according to the table. For example, if table is named Employee, then the class is also named Employee. This is mandatory if you do not want to override the defaults.
  2. Derive the class from Base class of ActiveRecord package. For example, the Employee class needs to be derived from Base::ActiveRecord.
Thats it just two steps. No need to declare any instance variable or any getter/setter. So how does Rails gives you the data? It does it as follows:
  1. When the ORM object is created Rails reads the schema of the table and through meta-programming, creates corresponding instance variables in the ORM object.
  2. Next, Rails populates the object with the data from the table.
Using meta-programming and reflection Rails dynamically does everything. In the next post the third round will start on the basis of Query Language supported by both.
You will have heard of shiny new web application framework called Ruby-on-Rails also known as RoR or simply Rails. It provides complete stack from ORM framework to Web Service. From this post onwards for next couple of posts I will compare and contrast between different components of JEE and Rails. I will begin with Hibernate from JEE and Active Record from Rails. The Round I of the Active Record v/s Hibernate will be on the basis of Mapping

The very first aspect is mapping. Hibernate requires the POJO (Java objects that represents the tables) be mapped with the tables using XML. That means if there is even a slight change in the Database schema such as the length of a particular field is changed, then you will have to make changes not only to the corresponding POJO but also to the mapping file. If you fail to do so, then run-time exception is the most common and the least problem that you will face.

Now lets look at Active Record. The driving principle of Rails is “Convention-over-Configuration” (but version 2.0 is deviating from it, more on that later). So , to map a class to a database table you just have to follow conventions. The conventions are

  1. The class derives from ActiveRecord::Base i.e. Base class of ActiveRecord module
  2. The name of the class must be same as that of the table
  3. The name of the class should start with a capital letter (though this applies to all Ruby classes)
Thats it. No XML, no configuration. Even if there is a change in the table, the corresponding class will adapt to it automatically at runtime through reflection and meta-programming. So that is the difference between Active Records and Hibernate on the basis of Mapping. In the next post I will continue comparing the two on how ORM classes are defined.

Authors Note: I am really sorry for the gap between the posts. It wont happen again (this time for sure). For now on you can expect atleast one post in a week.


Sun created JSF as a competition for ASP.net. Though the idea is good, yet, the Sun stuck with the aspect of configuration. So if I need the framework to manage any of my beans automatically, then I need to specify it in faces-config.xml. Lets say my bean is named ResultBean, then I will have to put it as follows

<managed-bean>


<managed-bean-name>Result</managed-bean-name>

<managed-bean-class>org.me.ResultBean</managed-bean-class<

<managed-bean-scope>session</managed-bean-scope>

<managed-bean>

Now let us say there is another bean named ValueSetter, which is also a managed bean, wants to access the ResultBean, then the technique is classic Java technique. It goes something like as under

  • Get a reference to FacesContext which essentially is ServletContex when compared to Servlet
  • From FacesContext reference get current Application object
  • From Application object get a reference to VariableResolver object
  • Call resolveVariable method on it passing reference of the FacesContext and the name of the bean as string (not the class name)

In code it will be as follows

FacesContext context = FacesContext.getCurrentInstance();

ResultBean bean = (ResultBean) context.getApplication().getVariableResolver().resolveVariable(context, “Result”);

As you have seen how many objects need to be used. Cant it be made simpler?

JSP provides following implicit objects

  1. request
  2. response
  3. session
  4. page
  5. application
  6. exception
  7. pageContext
  8. out

The first question any interviewer or external asks is to name all the implicit object. The next question is which Servlet object corresponds to which JSP implicit object. So from this post onwards I will discuss this aspect. This post looks at request object.

You will be knowing that when JSP is compiled, it becomes a Servlet. HttpServletRequest is one of the two objects passes as arguments to the service method of the Servlet class. In case of compiled JSP, the name of the service method is _jspService, the only method that a developer cannot override. When the compilation takes place the request object is accessed as an object of HttpServletRequest. To cut a long story short request object corresponds to HttpServletRequest. In the next post I will discuss about response and out objects. Till then keep visiting…

Why Annotations cant be used always?

That exactly what my question is. JEE 5 gives you a choice to use annotations instead of configuration files almost everywhere – even in Servlets. However, why such a facility be extended to frameworks such as JSF where I still have to use configuration files.

Frameworks including JSF needs to be compilation stage as well as configuration stage to deploy them successfully. If servlets can be deployed without configuration file(web.xml), then why such a facility is not being extended to JSF? I am leaving out Struts because its outside Sun’s control. And get me wrong, I am not against configuration. My only question is when an alternative is available and such an alternative can ease development, then why is not being implemented? With that I stopping my rant.

In the last post I ranted about problems with GMap. However, this time its not a rant. Thats right EJB 3.0 is a step in the right direction. The reason are as follows

1. No more configuration files. Annotations takes care of all the configuration. For example to tell container that a class Test is a Session bean, you will annotate it as follows
@Stateless public class Test{ //rest of the class }
2. No more home or remote interfaces. Just a simple Java class with annotations. Simple Java classes are known as Plain Old Java Objects or POJO. All the types of Beans in EJB 3.0 are based on POJO. So you dont need to extend or implement any interface. Take a look at the above example. It is a Stateless Session Bean, yet, does not extends or implements any Remote, Home or Bean interface.

3. Clients dont need to depend on JNDI. Instead dependency injection is used. More about dependency injection in next post.

4. Entity Beans now have full support for CRUD operations. CRUD is short for Create, Retrieve, Update and Delete. Prior to version 3.0, Entity Beans supported only limited Retrieve operation (also known as Select operation) that did not include full joins.

Thats all about new features of EJB 3.0. In the future posts, I will discuss about development using EJB 3.0. Visit again…


Follow

Get every new post delivered to your Inbox.