Wednesday, October 7, 2009

First EJB3.0 example, EJB3.0 tutorial, @EJB not working

Here I am putting very easy example for EJB3.0. It has Session Bean, Entity Bean and JPA example. All these examples are in very step wise. I have used glassfish application server. For other application server I was getting error when I used @EJB. So decided to use glassfish application server.

1. Install glassfish-tools-bundle-for-eclipse-1.1.exe
2. start -> All Program -> GlassFish tool bundle for eclipse 1.1 -> GlassFish tool bundle for eclipse
3. File -> New Project -> EJB
4. Put name of Project say school -> click on add project to EAR say SchoolEAR
5. File -> New Project -> Dynamic Web Project -> Put name of Project say schoolWEB -> click on add project to EAR say SchoolEAR
6. Click on SchoolWEB -> Webcontent -> Right click and create one JSP page say search.jsp

search.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Student Search Page</title>
</head>
<body bgcolor="green"><h1> ABC SCHOOL </h1>
<table align="center">
<tr><td>Enter Student Roll </td><td><input type="text" name="roll"></td>
</tr><tr><td><input type="submit" name="searchStudent" value="Search""></td>
</tr>
</table>
</body>
</html>

7. Go to Server Pan and start server (Bundled GlassFish V2.1)
8. Add project SchoolEAR to server
9. Run http://localhost:8082/SchoolWEB/search.jsp (Just for test whether page is coming) now you should able to see the search page in your browser.

Now Add one servlet:
1. Go to School Project -> ejbModule -> create Servlet -> put Package Name: com and classname: SearchServlet -> Finish
2. SearchServlet.java

package com;
import java.io.IOException;
import javax.ejb.EJB;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class SearchServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public SearchServlet()
{ super();
System.out.println("SearchServlet IS CALLING");
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("THIS IS SEARCH SERVLET");
int roll = Integer.parseInt(request.getParameter("roll"));
System.out.println("Roll Entered :: "+roll);
}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("THIS IS DO POST METHOD");
}
}

3. Your web.xml of SchoolWEB should be like this: (Path C:\GlassFish_Workspace\EJB3\Practice_1\SchoolWEB\WebContent\WEB-INF\web.xml)
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>SchoolWEB</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<description></description>
<display-name>SearchServlet</display-name>
<servlet-name>SearchServlet</servlet-name>
<servlet-class>com.SearchServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>SearchServlet</servlet-name>
<url-pattern>/SearchServlet</url-pattern>

</servlet-mapping>
</web-app>

NOTE: One problem with this version of Glassfish that every time when you change code you have to clean your project and restart server. :(

4. Change little bit your JSP code to call this new servlet.
Search.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Student Search Page</title>
</head>
<body bgcolor="green">
<h1> ABC SCHOOL </h1>
<form action="SearchServlet">
<table align="center"><tr>
<td>Enter Student Roll </td><td><input type="text" name="roll"></td>
</tr><tr><td>
<input type="submit" name="searchStudent" value="Search""></td>
</tr>
</table>
</form>
</body>
</html>

5. Clean your all project and restart the servercall on browser: http://localhost:8082/SchoolWEB/search.jsp
Put some roll number and see the server log file (say entered 110)you should get the output like INFO: THIS IS SEARCH SERVLETINFO: Roll Entered :: 110

Now add Session Bean: [IMPORTANT]
1. Click on School project -> ejbModule -> Right click -> New -> Interface -> package com and class name: ISearchBean

ISearchBean.java
package com;
public interface ISearchBean {
public String search(int roll);
}
2. Click on School project -> ejbModule -> Right click -> New -> SessionBean -> package com and class name: SearchBean
SessionType: StatelessSearchBean.java

package com;
import javax.ejb.Stateless;
@Statelesspublic class SearchBean implements ISearchBean{
public SearchBean() { }
@Override
public String search(int roll) {
if(roll == 110){ return "Binod Kumar Suman"; }
return "Name does not match";
}
}

Note: You used here first EJB annotation @Stateless :)
3. Change servlet to call this session bean with use of @EBJ annotation

SearchServlet.java
package com;
import java.io.IOException;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SearchServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@EJB
private ISearchBean searchBean;

public SearchServlet() {
super();
System.out.println("SearchServlet IS CALLING");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("THIS IS SEARCH SERVLET");
int roll = Integer.parseInt(request.getParameter("roll"));
System.out.println("Roll Entered :: "+roll);
if(searchBean == null){ System.out.println("SearchBean is still null"); }
else{ System.out.println("Search Bean is working fine");
System.out.println("Result :: "+searchBean.search(roll)); }
}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("THIS IS DO POST METHOD"); }
}

4. Now run the jsp file from browser:http://localhost:8082/SchoolWEB/search.jsp
Put roll number 110and check server output:
INFO: SearchServlet IS CALLINGINFO: THIS IS SEARCH SERVLET
INFO: Roll Entered :: 110
INFO: Search Bean is working fine
INFO: Result :: Binod Kumar Suman

*********** NOW ADD JPA Persistence part *****************
Now we will see how to save data using EJB3.0 JPA (Plesae get introduction of EJB3.0 JPA from this URL http://binodsuman.blogspot.com/2009/10/jpa-introduction-what-is-jpa-java.html)
1. To use JPA in EJB3.0, you have to add persistence.xml in META-INF folder, thatshould have your database connection information.
2. Create one entity class say student
student.java in com.entity folder

package com.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "studentinfo")
public class Student {
private int roll; private String name; private String cell;
@Id
@Column(name="roll",unique=true,updatable=true)
public int getRoll() { return roll; }

public void setRoll(int roll) { this.roll = roll; }
@Column(name="sname",updatable=true)
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getCell() { return cell; }
public void setCell(String cell) { this.cell = cell; }

}
persistence.xml in (C:\GlassFish_Workspace\EJB3\Practice_1\School\ejbModule\META-INF\persistence.xml)
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence persistence_1_0.xsd" version="1.0">
<persistence-unit name="student_unit" transaction-type="RESOURCE_LOCAL">
<provider>oracle.toplink.essentials.PersistenceProvider</provider>
<class>com.entity.Student</class>
<properties>
<property name="toplink.logging.level" value="FINEST" />
<property name="toplink.jdbc.driver" value="org.postgresql.Driver" />
<property name="toplink.jdbc.url" value="jdbc:postgresql://localhost:5432/postgres" />
<property name="toplink.jdbc.user" value="postgres" />
<property name="toplink.jdbc.password" value="suman" />
</properties>
</persistence-unit>
</persistence>

I have used here postgres sql, you can use any database.Create one table studentinfo
CREATE TABLE studentinfo(
roll int4 NOT NULL,
sname char(100),
cell char(15), CONSTRAINT "studentinfo_PK" PRIMARY KEY (roll)
)

Now change in SearchBean.java

package com;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import com.entity.Student;
@Stateless
public class SearchBean implements ISearchBean{
private static EntityManagerFactory emf;
private static EntityManager em;
public SearchBean() { }
@Override
public String search(int roll) {
if(roll == 110){ return "Binod Kumar Suman"; }
return "Name does not match";
}

@Override
public void saveStudent(Student student) {
System.out.println("IN SEARCH BEAN TO SAVE STUDENT RECORD");
try{
emf = Persistence.createEntityManagerFactory("student_unit");
em = emf.createEntityManager();
// Begin transaction
em.getTransaction().begin();
em.persist(student);
em.getTransaction().commit();
// Close this EntityManager
em.close();
System.out.println("***** RECORD SAVED SUCCESSFULLY ***************");
}
catch(Exception e){
System.out.println("SOME PROBLEM DURING SAVE STUDENT :: "+e);
e.printStackTrace(); }
}
}
And change in SearchServlet.java

package com;
import java.io.IOException;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.entity.Student;

public class SearchServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@EJB
private ISearchBean searchBean;
public SearchServlet() {
super();
System.out.println("SearchServlet IS CALLING");
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("THIS IS SEARCH SERVLET");
int roll = Integer.parseInt(request.getParameter("roll"));
System.out.println("Roll Entered :: "+roll);
if(searchBean == null){ System.out.println("SearchBean is still null"); }
else{ System.out.println("Search Bean is working fine");
System.out.println("Result :: "+searchBean.search(roll));
Student student = new Student();
student.setRoll(150);
student.setName("Manish");
student.setCell("12345678");
searchBean.saveStudent(student);
System.out.println("******** One record of Student has been saved ********");
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("THIS IS DO POST METHOD"); }
}

Now you can http://localhost:8082/SchoolWEB/search.jsp and put any roll number. Onc student record would be saveed in database.
Easy ...................... :)

Sunday, October 4, 2009

JPA Introduction, What is JPA, Java Persistence API tutorial

Java Persistence API (JPA) provides POJO (Plain Old Java Object) standard and object relational mapping (OR mapping) for data persistence among applications. Persistence, which deals with storing and retrieving of application data. One of the great benefits of JPA is that it is an independent API and can nicely integrate with J2EE as well as J2SE applications.

A fundamental question for many Java developers is "Why JPA? Why do I need to know how to use this API when object-relational mapping tools like Hibernate and Toplink are already available?" The answer is that JPA is not a new technology; rather, it has collected the best ideas from existing persistence technologies like Hibernate, TopLink, and JDO. The result is a standardized specification that helps you build a persistence layer that is independent of any particular persistence provider.

Although it all started with entity beans and is packaged with Java EE 5.0, JPA can be used outside the container in a Java SE environment.

What is JPA?
JPA is just an specification from Sun, which is released under JEE 5 specification. JPA standardized the ORM persistence technology for Java developers. JPA is not a product and can't be used as it is for persistence. It needs an ORM implementation to work and persist the Java Objects. ORM frameworks that can be used with JPA are Hibernate, Toplink, Open JPA etc.

These days most of the persistence vendors are releasing the JPA implementation of their persistence frameworks. So, developers can choose the best ORM implementation according to the application requirement. For example, production can be started from the free versions of ORM implementation and when the needs arise it can be switched to the commercial version of the ORM framework. You can switch the persistence provides without changing the code. So, ORM framework independence is another another big benefit of JPA.

Here are the benefits of JPA
1. Simplified Persistence technology
2. ORM frameworks independence: Any ORM framework can be used
3. Data can be saved in ORM way
4. Supported by industry leaders

ORM frameworks
Here are the list of ORM frameworks that can be used with JPA specification.
Hibernate
Toplink
iBatis
Open JPA

Why JPA?
1. JPA is standardized specification and part of EJB3 specification
2. Many free ORM frameworks are available with can be used to develop applications of any size 3. Application developed in JPA is portable across many servers and persistence products (ORM frameworks).
4. Can be used with both JEE and JSE applications
5. JSE 5 features such as annotations can be used
6. Both annotations and xml based configuration support
source: http://roseindia.net/jpa/jpa-introduction.shtml

The persistence.xml file is a standard configuration file in JPA. It has to be included in the META-INF directory that contains the entity beans. The persistence.xml file must define a persistence-unit with a unique name in the current scoped classloader. The provider attribute specifies the underlying implementation of the JPA EntityManager. In JBoss Application Server, the default and only supported / recommended JPA provider is Hibernate.
You do not have to specify the persistence provider if you’re using the default persistence provider integrated with your Java EE 5 container. For example, if you want Hibernate’s persistence provider in the JBoss Application Server or TopLink Essentials persistence provider with Sun GlassFish or the Oracle Application Server, you don’t have to define the provider element in persistence.xml. But if you decide to go with the EJB 3 persistence provider from the GlassFish project with either JBoss or Apache Geronimo, then you must specify the provider element as follows:

<provider>oracle.toplink.essentials.PersistenceProvider</provider>

Obviously this example specifies Oracle TopLink as the persistence provider; you can specify the provider element for Hibernate as follows:

<provider>org.hibernate.ejb.HibernatePersistence</provider>

This is helpful when using JPA outside the container.


Template of persistence.xml
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0"> <persistence-unit name="pu1"> <provider>oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider</provider> <class>entity.Customer</class> <class>entity.Order</class> <properties> <property name="toplink.jdbc.driver" value="<database driver>"/> <property name="toplink.jdbc.url" value="<database url>"/> <property name="toplink.jdbc.user" value="<user>"/> <property name="toplink.jdbc.password" value="<password>"/> <property name="toplink.logging.level" value="INFO"/> </properties>
</persistence-unit>
</persistence>

Saturday, October 3, 2009

JPA example outside the container, jpa standalone application example

One simple JPA example outside the container

1. Create one java project in Eclipse (Say JAPDEMO)
2. Put toplink-essentials.jar and postgresql-8.1dev-403.jdbc2ee.jar in project (into classpath)
3. put Userinfo.java into JAPDEMO\src folder
4. put Client. java into JAPDEMO\src folder
5. put persistence.xml into JAPDEMO\src\META-INF folder.
6. Setup a database and make sure you can access it with the correct given information. I used Postgres SQL and I have put the jar for this database.I also used a simple "userinfo" table for my testing, columns: id, name, fullName, passwordinfo, email.

Userinfo.java
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Userinfo implements Serializable {
@Id
private int id;
private String email;
private String fullname;
private String passwordinfo;
private String name;
private static final long serialVersionUID = 1L;

public Userinfo() { super(); }
public int getId() { return this.id; }
public void setId(int id) { this.id = id; }
public String getEmail() { return this.email; }
public void setEmail(String email) { this.email = email; }
public String getFullname() { return this.fullname; }
public void setFullname(String fullname) { this.fullname = fullname; }
public String getPassword() { return this.passwordinfo; }
public void setPassword(String password) { this.passwordinfo = password; }
public String getName() { return this.name; }
public void setName(String name) { this.name = name; }
}

Client.java
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import oracle.toplink.essentials.ejb.cmp3.EntityManager;

public class Client {
public static void main(String[] args) {
EntityManagerFactory emf; emf = Persistence.createEntityManagerFactory("sumanunit", new java.util.HashMap());
EntityManager entityManager = (EntityManager) emf.createEntityManager(); entityManager.getTransaction().begin();
Userinfo user = new Userinfo();
user.setId(2);
user.setEmail("binod@abc.com");
user.setFullname("Binod Suman");
user.setPassword("minmax");
user.setName("Binod");
entityManager.persist(user);
entityManager.getTransaction().commit(); }
}

persistence.xml
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence persistence_1_0.xsd" version="1.0"> <persistence-unit name="sumanunit" transaction-type="RESOURCE_LOCAL"> <provider>oracle.toplink.essentials.PersistenceProvider</provider>
<class>Userinfo</class>
<properties> <property name="toplink.logging.level" value="FINEST" />
<property name="toplink.jdbc.driver" value="org.postgresql.Driver" />
<property name="toplink.jdbc.url" value="jdbc:postgresql://localhost:5432/postgres" />
<property name="toplink.jdbc.user" value="postgres" />
<property name="toplink.jdbc.password" value="suman" />
</properties>
</persistence-unit>
</persistence>

compile the code and see the database with one new entry. :)