My Java World

A blog about Java technology.

  • Categories

  • Archives

  • Flickr Photos

    Segundo dia (second day)

    Segundo dia (second day)

    Segundo dia (second day)

    More Photos

Using RAD 7.0 (Rational Application Developer) with EJB3 on Websphere 6.1

Posted by jrjuniorsp on June 18, 2008

RAD 7.0 (Rational Application Developer) is a complete IDE from IBM to work with Java application. However the version 7.0 does not offer support for EJB3 (if you want to full support, you must try out the version 7.5 Beta), but you can use it to create your EJB3 project without problem. In this article I am going to show you how to do that in a simple way.

First of all, you must have installed the Websphere 6.1 with Service Pack for EJB 3. If you do not know how to install it, check out this post.

Creating the Enterprise Application Project

Open the RAD 7 and the J2EE Perspective. Then right-click on Package Explorer and go to New -> Enterprise Application Project
Put the Project name (in my case Test) and click on Finish button.

You are going to see on Package Explorer the project called Test, however RAD will complain about an error “A J2EE Enterprise Application must contain one or more modules. Test/META-INF application.xml”. It happens because none project have been added to EAR project yet.

Creating the EJB Project

Important: DO NOT CREATE AN EJB PROJECT USING RAD WIZARD!!!. If you create an EJB Project using RAD Wizard, it will create the files used for EJB 2.1, not 3.0.
So, what kind of project should I create? Answer: Create a simple Java Project.
You can go to Java perspective, right click on Project Explorer and go to New -> Project. In my case, I’ve created a Java project called TestEJB.
After the project is created, it is time to add it as a Project Utility in the EAR and also add it (manually) as a EJB module.

Adding the EJB Module to the EAR

Open the EAR Deployment Descriptor (application.xml) in J2EE Perspective. Click on Module tab and then Add the Java Project as Project Utility JARs.

After that, go to Source tab and insert the following code:


	<module>
		<ejb>TestEJB.jar</ejb>
	</module>

Save the application.xml file and you will notify that RAD will not complain about the previous error anymore.

Using annotations

If you have Websphere 6.1 + EJB3 service pack installed, you will be able to use the EJB3 Annotations.
If you do not want to use the ejb-jar.xml file (it is recommended), you must provide, at least, one class ANNOTATED, otherwise Websphere will not start the application.
So, just for test, create an Interface (File -> New -> Interface). Put it into stateless package and give it a name: TestComponent. Its content is below:


package stateless;

public interface TestComponent {

	public void doSomeStuff();

}

After that, let’s create a class that implements this interface. Go to File -> New -> Class, put in the same package (stateless) and put the name: TestComponentBean. The content is below:


package stateless;

import javax.ejb.Remote;
import javax.ejb.Stateless;

@Stateless
@Remote(TestComponent.class)
public class TestComponentBean implements TestComponent {

	public void doSomeStuff() {
		System.out.println("Hello EJB3 World in Websphere 6.1 + RAD 7");
	}
}

Done! Our EJB Project is created and ready to be used. Also, a simple component has been developed.

Creating a Web Project as Client

To make sure our EJB Project, as well as our first component are working, let’s create a Web Project as client to call the EJB component.
Open the Web perspective and create a new Dynamic Web Project. In my case, I’ve created with the name TestWeb. Make sure to check the option Add project to an EAR and choose the Test ear.
Right after the Web project is created, you must associate it with the EJB project. To do that simply right click on TestWeb -> Properties -> J2EE Modules Dependencies. Check the EJB Project.

Now the Web Project will recognize the TestComponent interface from TestEJB project.

Create an Servlet to call the EJB Component, for instance: TestServlet and insert the following code:


package servlets;

import java.io.IOException;

import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import stateless.TestComponent;

public class TestServlet extends javax.servlet.http.HttpServlet {
	private static final long serialVersionUID = 1L;

	@EJB
	private TestComponent testComponent;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//Call the method from EJB component
		testComponent.doSomeStuff();
	}
}

To run the code, right-click on TestServlet, go to Run As -> Run on Server. After the server is started, you should see on the Console the phrase:


The article is over. Any question, comment, feedback are welcome. I hope this article be useful for anyone else.

Posted in Java, Websphere | No Comments »

Applying EJB3 Service Pack on Websphere 6.1

Posted by jrjuniorsp on June 6, 2008

Nowadays, if you are going to get started a new Java Enterprise Application, you probably will choose the EJB3 technology.

One of the most famous Java Application Server, Websphere, does not bring EJB3 as default, therefore you must install an EJB3 Service Pack if you want to use it.

Fortunately the installation process is simple, even in Windows or Linux environments. There is a GUI to help us on installation process. However there are some details you must pay attention:

  1. Which is your current Websphere version?
  2. EJB3 Service Pack runs only on versions equal or greater than 6.1.0.13
  3. If you have other service pack, such as WebService, it must be in the same version.
  4. Before apply the patch, MAKE SURE all websphere process are stopped.

Finding out the WebSphere version

If you are using Webpshere from a fresh installtion, probably the version you are using is the 6.1.0.0. If you are using a version which comes with RAD 7, probably is it:6.1.0.2. In both cases, you must upgrade the Websphere before apply the EJB3 service pack.

If you have no idea which version your websphere is, let’s check it out. Basically there are two ways to do that.

  1. Go to the <WAS>/bin directory (by default in Linux is /opt/IBM/Websphere/AppServer/bin) and run the following command: ./versionInfo.sh. This command will show up the version of Websphere, as well as the version of all services packs, if any. An example from my local machine:
    Product List
    --------------------------------------------------------------------------------
    WEBSERVICES              installed
    EJB3                     installed
    BASE                     installed
    
    Installed Product
    --------------------------------------------------------------------------------
    Name                     WebServices Feature Pack
    Version                  6.1.0.17
    ID                       WEBSERVICES
    Build Level              cf170819.04
    Build Date               5/15/08
    
    Installed Product
    --------------------------------------------------------------------------------
    Name                     WebSphere Application Server Version 6.1 Feature Pack for EJB 3.0
    Version                  6.1.0.17
    ID                       EJB3
    Build Level              cf170821.02
    Build Date               5/27/08
    
    Installed Product
    --------------------------------------------------------------------------------
    Name                     IBM WebSphere Application Server
    Version                  6.1.0.17
    ID                       BASE
    Build Level              cf170821.07
    Build Date               5/28/08
    
    --------------------------------------------------------------------------------
  2. Start the WAs and go to its console administrator, through the link: http://localhost:9060/ibm/console. In the top right corner, there will be the Websphere version, like image below:

Downloading the EJB3 Service Pack

As I already said, the EJB3 Service Pack must be applied in a Websphere version equal or greater than 6.1.0.13, however the Service Pack itself is always the same, in other words, the file you must download is the same for any Websphere version.

You can download the file from the link: http://www-1.ibm.com/support/docview.wss?rs=177&uid=swg21287579.

Although this topic will learn you how to apply this patch, maybe you want more information. In this case, you can get more information directly from the official IBM’s site.

Downloading the Update Installer

Update Installer is a tool used to update the Websphere version. After version 6.1, Websphere does not bring this tool by default, thus you need to download it separately.

The link to this tool is: http://www-1.ibm.com/support/docview.wss?rs=180&uid=swg24012718.

After download and extract it, go to its directory and run its installer. It is a GUI installer. By default, it is installed into <WAS directory>/UpdateInstaller.

Downloading and updating Websphere version

I recommend you to download the latest Websphere version. On last June 3rd, the version 6.1.0.17 was released. The link to download the files is: http://www-1.ibm.com/support/docview.wss?rs=180&uid=swg24019091.

YOU DO NOT NEED to download all the files. If you are using only the EJB3 Service Pack, then you must download the AppServer and AppSrv EJB 3.0 FP.

After you downloaded the files, actually two files with .pak extension, it is time to install them.

Firstly, you must install the AppServer itself. To do that, stop all websphere process and then copy the file to the <WAS>/UpdateInstaller/maintance directory, in my case for instance, /opt/IBM/Websphere/UpdateInstaller/mainstance. (make sure to make this process as root).

Now, go to <WAS>/UpdateInstaller and run the ./update.sh file. A GUI will come up and simply click on next several times. After that, your Websphere will be updated to version 6.1.0.17. (If you want, you can check again its version either through versionInfo or within the Admin Console.

Applying EJB3 Service Pack

You should be notified that in the last step we did not install the AppSrv EJB 3.0 FP file. Why? Because it will be installed with the EJB3 Service Pack together.

To do that, extract the EJB3 Service Pack you downloaded previously and go to its directory (probably a directory called EJB3). There, you will find a file called update.sh. Run it.

A GUI will come up. Like the Update Installer, click next several times until the screen where the installation will ask for the AppSrv EJB 3.0 FP. Select the file you downloaded previously and click NEXT again. The installation process will get started.

When the installation finishes, try to run the versionInfo.sh command to make sure the EJB3 service pack was applied successfully. If everything is ok, then your Websphere will be updated and ready to run EJB3 components.

I hope this article be useful for someone else. Any problem, question or feedback, please leave a comment.

Posted in Java, Websphere | 2 Comments »

How to setup a DataSource on Websphere 6.1 for MySQL - step by step

Posted by jrjuniorsp on May 26, 2008

In this article I will show up how to setup a DataSource on Websphere 6.1 for MySQL step by step.

After you read this article, you will be capable to create a DataSource on Websphere 6.1 using MySQL database. Also, this article can be useful if you want to use another database, such as DB2, Oracle and so on.

Setting up a DataSource

Basically, there are 3 steps to create a DataSource on Websphere:

  1. Create a JDBC Provider
  2. Create a J2C
  3. Create the DataSource

Creating a JDBC Provider

First of all, you must start the Websphere server and open its admin console: http://localhost:9060/ibm/console/. On Admin Console, expand the Resources -> JDBC section.

Click on JDBC Provider link and a list of current JDBC providers will appears for you. By default, WAS 6.1 brings only Derby JDBC Provider already setup. We are going to create a new one for MySQL. Select the Scope and then click on New.

On the new screen, select User-Defined in Database type field (because WAS doesn’t have MySQL pre-defined), com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource in Implementation Class Name field and MySQL JDBC Provider in Name field.

After that, click on Next button. On next screen, you must inform the ClassPath of the JARs files. In my case, I copied the file mysql-connector-java-5.1.6-bin.jar to the <WAS-HOME>/lib directory.

Click on Next and on the next screen click on Finish. The first screen will come up and then you must click on Save link to commit the information to Websphere.

Creating a J2C

J2C is a way to create an authentication for our DataSource. The easiest way to create it is go to Data Sources section, click on New and then click on the link create a new J2C authentication alias.

On the new screen, click on New button and fill up the fields:

Click on OK and then Save link.

Creating the DataSource

Go to Data Sources section and click on New. On the new screen, insert the Data source name, JNDI name and select the J2C.

Note: The JNDI name default is jdbc/ plus JNDI name.

On the next screen, select the JDBC Provider previously created.

On the next two screens, just click on Next and then Finish. To commit the changes, click on Save link.

We are almost done. We need now to setup a couple of parameters. To do that, click on your Data Source and onto the new screen, click on Custom properties link.

On Custom properties, you must change the value to databaseName and serverName. (there are also other properties that you are free to change them if you want).

After the changes are done, it is time to test the DataSource. Back to the Data sources section, check the datasource you want and click on Test connection button. A message should appears.

We’re done! The DataSource has been created, tested and now it is ready to be used within Websphere Application Server v6.1

Creating a Web Application to access the DataSource

If you are using Websphere 6.1, probably you are using RAD 7 (Rational Application Developer) as well.

First of all, you must create a Dynamic Project. Then go to Web perspective and select the menu New -> Dynamic Web Project. Insert a project name and click finish (for this example, you do not need to create an EAR project).

The second step is to link the DataSource in our Web Project. To do that, simply open the Deployment Descriptor (double click on it).

On the new screen, go to References section. There, click on Add button and then Resource reference. Fill up the fields like below:

Back to the References section, click on the Reference just created and in the Websphere bindings, insert the JNDI name of the datasouce created into Websphere.

After that, both files (web.xml and ibm-web-bnd.xmi) will be configured. Your web application can call the DataSource through the alias: jdbc/ApplicationDS.

Below following a piece of code which uses the DataSource. This code can be used in a Servlet, JSP, ManagedBean and so on.


        try {
            Context ctx = new InitialContext();
            DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/ApplicationDS");
            Connection con = ds.getConnection();
            PreparedStatement query = con.prepareStatement("select * from customers");
        } catch (Exception e) {
            e.printStackTrace();
        }

Look at the line number 3, in this line we are calling the DataSource from Websphere.

Conclusion

I really hope this topic be useful for anyone else. It is a simple and fast way to create a DataSource (and use it) in Websphere 6.1 environment.

Posted in Java, Websphere | Tagged: , , | 1 Comment »

How to setup a DataSource in JBoss 4.2 and Glassfish

Posted by jrjuniorsp on May 14, 2008

When we are working on a JEE environment, it is common to use a DataSource to get the connection from the database. If you are using EJB in fact, you must setup a DataSource to be used by the Entities.

In this blog, I’ve already talked about DataSource in Tomcat. Now it is time to work around the DataSource in a Application Server, in our case, JBoss 4.2 and Glassfish.

Setting up a DataSource in JBoss 4.2

First of all, you must have JBoss installed, of course. If you want to learn how to install JBoss, here there is a simple but useful topic about it.

Basically to setup a DataSource in JBoss, you should create a XML file and add the JDBC driver in the classpath. Both the XML file and the JDBC driver depends on which database you are going to use. In this topic, we are going to use MySQL, however you are free to use others databases as well.

Before get started the configuration, make sure your database is already running and you have a database created. In MySQL for instance, you can create a database through the command: create database test;

Creating the XML file and copy the JDBC to the proper directory

JBoss brings us some XML examples. You can reach them into $JBOSS_HOME/docs/examples/jca. There you will find many XMLs. Copy the xml regarding your database (in my case, mysql-ds.xml) to the directory $JBOSS_HOME/server/default/deploy.

Open this file using your preferred text editor and edit the connection-url, user-name, password. Below following an example:


<?xml version="1.0" encoding="UTF-8"?>
<datasources>
  <local-tx-datasource>
    <jndi-name>MySqlDS</jndi-name>
    <connection-url>jdbc:mysql://localhost:3306/test</connection-url>
    <driver-class>com.mysql.jdbc.Driver</driver-class>
    <user-name>database_username</user-name>
    <password>database_password</password>
    <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>
    <metadata>
       <type-mapping>mySQL</type-mapping>
    </metadata>
  </local-tx-datasource>
</datasources>

After that, you must copy the JDBC driver from your database to the directory $JBOSS_HOME/server/default/lib. (Mysql uses the mysql-connector-java driver. It can be downloaded from MySQL official website. If you are not using mysql at all, check out your database documentation to figure out which files you must copy to the lib directory).

Done! Our DataSource in JBoss has been setup and it is ready to be used. Let’s learn how to use this DataSource within a Web Application.

Creating a Web Application that uses the DataSource

Create yourself a Web Application to test the DataSource. In my case, I am using Eclipse Europa, then I should open the JEE Perspective, go to Package Explorer, right click there and choose New -> Enterprise Application Project (you can create a simple Dynamic one if you prefer). Put the name of the EAR, in my case TestDS and click next twice. In the Modules, add only the Web Modules (by default, the web modules’s name is: TestDSWeb).

After these steps, both the EAR and the WEB project should appear on the Package explorer.

Now it is time to create the index.jsp page. Expand the TestDSWeb project, right click on WebContent -> New -> JSP. Put the name index.jsp. The content of the JSP file looks like:


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h3>Test</h3>
    <a href="TestServlet">Click here for test</a>
</body>
</html>

The JSP has a hyperlink that calls a servlet called TestServlet. In fact, the TestServlet will call our DataSource previously created.

To create the servlet, right click on TestDSWeb -> New -> Servlet. Put the name TestServlet and the package servlets. Click on Next twice and uncheck the doGET and Constructor options. After that the Servlet will be created and its code looks like:


package servlets;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import javax.naming.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

public class TestServlet extends javax.servlet.http.HttpServlet {
    static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            InitialContext ctx = new InitialContext();
            DataSource ds = (DataSource) ctx.lookup("java:/MySqlDS");
            Connection con = ds.getConnection();
            PreparedStatement query = con.prepareStatement("select * from test");
            ResultSet rs = query.executeQuery();
            while (rs.next()) {
                System.out.println(rs.getString(2));
            }
            rs.close();
            con.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Stop now, breath and let’s take a look deeper in the code:

  • Line 19: we started a InitialContext object. Remember: it is used to get object from JNDI.
  • Line 20: we created the DataSource object through JNDI. To get the DataSource, you must use java:/ plus yourDataSource name. But where is the DataSource name? In the mysql-ds.xml file there is a tag called jndi-name. It is the name used there.
  • Line 21: we created the Connection object through DataSource.

The example ends here. You could see how is easy setup and use a DataSource. Next we are going to show up how to setup a DataSource in Glassfish.

Setting up a DataSource in Glassfish

If you are using Glassfish instead JBoss (btw, I prefer Glassfish when I am working with EJB 3), you can follow up this part of the topic to figure out how setup a DataSource on it.

The DataSource in Glassfish is set up through its Admin Console. As you will see, the process is made using a GUI (Web-based) and very simple. Before run the Admin Console, make sure you have the JDBC driver in your machine. Copy the file into $GLASSFISH/lib directory.

To access the Admin Console, start Glassfish and type the following URL: http://localhost:4848. By default, the Username is admin and Password is adminadmin, but of course you could change them in the installation process :)

The first thing to do is to create a Connection Pool. To do that, within Admin Console, go to Resources -> Connection Pools.

Now let’s add our connection pool. On the content, click on New button. On the new screen, put the Name choose Resource Type and Database Vendor. Look at my choice below:

Click on next after the fields are filled up. On the next screen, scroll down and you will find many options. Basically you have to change the following: DatabaseName, Password, ServerName, URL, User. After you change these fields, click on Finish button.

You will be redirected back to the Connection Pool screen. To test if your pool is working, click on it and on the next screen, click on Ping button. If a success message appears, means your pool was setup properly.

Now let’s setup the JDBC Resource itself. Click on it and then New button.

On the next screen, choose: JNDI Name and Poll Name (Description is not required). Remember: By convention, the JNDI Name must starts with jdbc/DataSourceName. In my case for instance, I’ve choosen jdbc/ConnectionTestDS.

Click OK and done, your DataSource is setup in Glassfish.

Creating a client

You can use the same example than used in JBoss to create a Client. However the JNDI call must be different. (Remember: the JNDI call in Glassfish is different than JBoss).

You can get your DataSource from Glassfish using the following line:


DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/ConnectionTestDS");

Look at the line above. You retrieves the DataSource in Glassfish using java:comp/env plus JNDI Name.

I hope the both examples, JBoss and Glassfish, be useful for anyone. It is useful when you are going to create a EJB3 Entity component (next topic).

Posted in Java | Tagged: , , , , , | No Comments »

How to create an EJB3 (Statefull Session Beans) in Eclipse Europa

Posted by jrjuniorsp on May 7, 2008

Again I am here to talk about EJB3. In this topic I am going to cover the creating of an EJB3 (Statefull Session Beans) in Eclipse Europa.

This topic is going to be similar than this one: http://myjavaworld.wordpress.com/2008/04/25/example-of-ejb3-session-bean-using-eclipse-europa-and-jboss/, except by the fact that this topic will cover Statefull session bean rather than Stateless Session Beans.

The big difference between them, it the statefull session beans keeps a state among different requests as long as stateless session beans loss the state when the request dies.

Hence, statefull sessions beans could be used when you need to keep a state, for instance, a cart object in an e-commerce application. Of course there are other differences, but it is the major.

Although statefull sessions beans seems more powerful than stateless, you have to keep in mind that this “power” has a cost to the server. When you are using a statefull session beans, the server must store them in any way. Hence, you must think well if you really need the Statefull instead Stateless.

Here, we are going to create a simple application. The session beans component has the responsibility to “count” how many time a certain link is clicked by the SAME user, therefore we need to use Statefull (to keep the state).

I am not going to show you many print-screen, so if you never build an EJB application into Eclipse, I advice you to take a look at the topic shown above.

Creating the project

Within eclipse environment, go to the J2EE perspective (it is the default) and right-click on Project Explorer and go to: New -> Enterprise Application Project. On the new screen, insert the Project name (I’ve used JavaEELesson) and click on Next twice. On third screen, click on New Module and choose the EJB module and Web module. Also, mark the checkbox Generate Deployment Descriptor.

You will see on the Package Explorer three projects: JavaEELesson, JavaEELessonEJB, JavaEELessonWeb.

Implementing the EJB Module

It is time to implement our Statefull Session Bean component. Remember the requirement: “we are going to create a component that counts how many time a certain link is clicked by one user. Even this user goes to other page and back into the same session, the count must be active.

Of course it is a silly requirement, but it can show us how to create a Statefull component.

Creating the Interface

Like the stateless, we need an interface. Right click on JavaEELessonEJB and go to: New -> Interface. On the new screen insert the Package Name(in my case I’ve used statefull) and then insert the interface name (in my case I’ve used Counter).

We are going to use two methods in this interface: count() that will increase +1 the count object and getCount() that will return the value of the count object. The code looks like below:


package statefull;

public interface Counter {
    public void count();
    public int getCount();
}

So far so good!!

Implementing the Interface

Now let’s create a concrete class to implement this interface. Right click on JavaEELessonEJB and go to: New -> Class. On the new screen, insert the package (statefull), name (CounterBean) and select the Counter interface.

The implementation of this class looks like below:


package statefull;

import java.io.Serializable;

import javax.ejb.Remote;
import javax.ejb.Stateful;

@Stateful
@Remote(Counter.class)
public class CounterBean implements Counter, Serializable {
    private static final long serialVersionUID = 1L;

    private int count;

    public void count() {
        this.count++;
    }
    public int getCount() {
        return this.count;
    }
}

Pay attention on the code. Look at the @Statefull annotation. Also, pay attention we are implementing the interface Serializable, but why? Because we need to store our object, so the easier way to do that is make our object Serializable. The rest of the code is simple, nothing special.

Our EJB component is done and ready for use.

Creating the Client through a WEB project

It is common a WEB project access the EJB components. If you are using Glassfish, you can simply gets the EJB component though DI using the annotation @EJB (when you are in a Enterprise Environment). If you are JBoss, you must use JNDI (look at the post above that talks about it).

In my case, I am using Glassfish, but you are free to use another Java EE Application Server as well.

Creating the JSP pages

In our project, we are going to create a couple of JSP pages. The first one is the famous index.jsp. It contains a link to a Servlet which calls the Statefull Session Bean and send the result to the result.jsp page. This page though, will show up the value of the counter.

Let’s get started by the index.jsp. Expand the JavaEELessonWeb and right-click on WebContent -> New -> JSP. Insert the file name index.jsp and click on Finish.

The content of the index.jsp page looks like:


<!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=UTF-8">
<title>Index</title>
</head>
<body>
    <h3>JavaEE Lesson Web application</h3>
    <a href="CounterServlet">Click here to count your click</a>
</body>
</html>

As you can see, the link calls a servlet called CounterServlet. We are going to implement it soon.

Now repeat the process and create a file called result.jsp. In this file, we are going to print out the result of a variable called counter. Code looks like:


<!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=UTF-8">
<title>result</title>
</head>
<body>
    <h3>Result</h3>
    <%= request.getAttribute("counter" ) %><br />
    <a href="index.jsp">Back to index page</a>
</body>
</html>

Nothing special above, huh? There is only a JSP tag to prints out the content of the object counter. Also, there is a link to the user get back to the index.jsp page.

Now it is time to create our Servlet. It’s name is CounterServlet. Right click on JavaEELessonWeb -> New -> Servlet. Insert the package servlets and the name CounterServlet. Click next twice and then uncheck the values: Contructor for Superclass and doPot. (we do not need these methods).

In the CounterServlet we need to call the EJB component. In Glassfish we could use the @EJB annotation. Inside the doGet method, you will call the methods to count the counter (count()) and then store the new counter in a variable (getCount()). Finally we will send the value to the request object and call the result.jsp file. The CounterServlet.java class looks like:


package servlets;

import java.io.IOException;

import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import statefull.Counter;

public class CounterServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
	static final long serialVersionUID = 1L;

	private Counter counter;

	protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
		//increase +1 on Count attribute from EJB component
		counter.count();
		//get the current value of the Count attribute
		Integer count = counter.getCount();
		//Send the value to request object
		request.setAttribute("counter", count);
		//redirect the page
		request.getRequestDispatcher("result.jsp").forward(request, response);
	}

	@EJB
	public void setCounter(Counter counter) {
		this.counter = counter;
	}
}

Now you can run your server (Right click on JavaEELessonWeb and choose your-server). When the index.jsp displays, click on the LINK and you will see the result.jsp priting out 1 (by the first step). Back to the index.jsp page and repeat the process several times. You will see the counter being increased, in other words, our EJB components is keeping its state.

As said, it is a silly application, but it can be useful for who is getting started in the Statefull Session Beans development using Eclipse Europa.

Posted in Java | Tagged: , , , | No Comments »

Adding Glassfish support on Eclipse Europa

Posted by jrjuniorsp on May 5, 2008

After these posts: Example of EJB3 (Session Bean) using Eclipse Europa and JBoss and Creating an EJB3 (session Bean) using Netbeans 6.1 and Glassfish, I am going to write a new one about how to add the Glassfish support on Eclipse Europa.

Actually the Glassfish supports is eligible in Eclipse Europa since version 3, however it does not come as default server. You must “download” it and then you can setup it on Eclipse.

Why Glassfish on Eclipse? As shown in the topics later, JBoss does not have the FULLY EJB3 support yet. If your preferred IDE is eclipse (like me) and you want to fully EJB3 support, make this integration can be an excellent choice.

Downloading Glassfish support on Eclipse

Open your Eclipse IDE and go to Window -> Preferences menu. In the new screen, expand the option Server and click on Installed Runtimes.

Click Add button and a new screen will come up. On this new screen, there is a link called Download additional server adapters.

On the new screen, all supported server will appear (but before, you must wait for eclipse to download them).

Choose Glassfish and click on Finish. Back onto Installed Server screen, choose Glassfish and click on Edit, a new window will come up. On this new window, you must select the Application Server Directory and then click on Finish.

Done, the server is configured and ready for use. You probably will see it on the Server view.

To start it, right-click (on Server view) and select start.

After the server starts, open your browser and type http://localhost:8080

It was a short topic, but hopefully it can be useful for anyone.

Posted in Java | Tagged: , | No Comments »

Creating an EJB3 (Session Bean) using Netbeans 6.1 and Glassfish

Posted by jrjuniorsp on April 29, 2008

After the post “Example of EJB3 (Session Bean) using Eclipse Europa and JBoss” I am going to show you how to create the same example but using NetBeans 6.1.

Netbeans 6.x brought nice features and let the web development much easier. You can create many things in a “.VS-style”, in other words, drag-and-drop components on the User Interface. A good example of this it is the Visual Java Server Faces features from NetBeans 6 and the Web Service module.

IMHO, I think the NetBeans 6 is a good tool, however it makes much “magic” and I do not like it. But I have to admit that some stuffs are really cool in Netbeans. I still prefer Eclipse Europa to create Web Application, as well as EJB3 applications, but Netbeans became my Ruby on Rails official IDE and I am also always using Netbeans for Java programs to see how it does work. This topic has the goal to show you how to create the same EJB3 project but in a different platform. After that, you can choose yourself what is the best tool for you (no flamewar, please).

Netbeans brings Glassfish Application Server as its official server. As Glassfish is the the RI (Reference Implementation) from JEE 5, it has some features that you cannot find (yet) in JBoss. An example of this is the @EJB annotation, that using DI approach, you can inject your EJB object in the client directly, thus avoid coupling.

Using Glassfish within Netbeans 6.1

When you are installing Netbeans, you will be asked about extra-programs. One of them is the Glassfish. If you choose the Glassfish in the installation process, it will be configured automatically within NetBean 6.1

To check out the Glassfish installation, open Netbeans and go to the tab Services (left window). Expand Servers option and you should see the Glassfish there.

If you want, you can start the server: right mouse click on Glassfish -> Start.

Creating an Enterprise Application Project

Let’s get started the code itself. The first thing to do is to create the Enterprise Application Project, or simply, EAR.

To do that, back to the tab Projects and right mouse click and select option New Project. On the new screen, select the Category Enterprise and then the project Enterprise Application, click next to go to the next screen.

On the next screen select the Project name and the Project Location. (In my example, I am going to use the name Test), click next again.

On the third screen, select the server (by default Netbeans brings Glasshfish), choose the Java Version (Java EE 5 by default), and select the EJB and Web module.

Note: By default, the EJB module’s name is “EAR name” plus “-ejb“. The Web module’s name is “EAR name” plus “-war“. However you are free to change these names.

When the projects are created, they will be shown on the Projects tab.

Creating our first EJB component (Stateless Session Bean)

On the Projects tab, expand the EJB module (in my case called “Test-ejb”). You will see some options, such as: Enterprise Beans, Configuration Files, Server Resources and so on. We will work around the Enterprise Beans, therefore right mouse click on Enterprise Beans -> New -> Session Bean.

On the screen that will come up, choose the EJB Name, Package, Session Type and Interface. For my example, I am using “TestEJB”,”stateless”,”Stateless”,”Remote”. Click fisnish when your fields are filled.

After the Session Bean is created, you will see the class (and the interface) in the Source Packages section, as well as the Bean in the Enterprise Beans section. In the main tab, the TestEJBBean.java will be opened automatically.

Our Stateless Session Bean was created into the stateless package, but now we have to implement it.

Open it (if it is closed) with double click on the TestEJBBean from Enterprise Beans section (you can open the file directly from the Source Package as well).

In the body of the class there is a comment “ // Add business logic below. (Right-click in editor and choose // “EJB Methods > Add Business Method” or “Web Service > Add Operation”)

So right mouse click in the editor and choose EJB Methods > Add Business Method. A new screen will come up. In your example, we will have only one method (called getMessage()) with String return. Hence, put in the field name getMessage and return type: String.

Done, our first EJB3 Session Bean object has been created. To check out the code it has created, you can open the class TestEJBBean (implementation) and the interface TestEJBRemote (remote interface). Different than Eclipse, where we put ourself the interface and the class name, Netbeans uses the pattern Object Name plus Remote or Local. Of couse you can change it yourself :)

The last thing to do is to implement the business method we just added. It is simple, only return a string message: Hello EJB World. The code looks like below:


package stateless;

import javax.ejb.Stateless;

@Stateless
public class TestEJBBean implements TestEJBRemote {
    public String getMessage() {
        return "Hello EJB World";
    }
}

Simple, huh?

Using the Web Module as EJB Client

We have already created the Web Module previously when the EAR has been created, so let’s use it as EJB Client.

When the Web module is created, by default Netbeans already creates a file called index.jsp in the Web Pages section. Open this file to add a call to the servlet. The code looks like below:


<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!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=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <h2>Hello World!</h2>
        <a href="TestServlet">Click here to call the EJB component</a>
    </body>
</html>

As you can see, we must create a servlet called TestServlet. it will call the EJB component when the link from User Interface is clicked.

To create the servlet itself, right click on Web project (in my case Test-web), New -> Servlet.

On the new screen, select the Class Name and the Package. On next screen, you can keep all options and click on Finish button. The Servlet will be created and its code will appear on the Main tab.

Much easier than JBoss, in Glassfish there is the annotation @EJB. When the container sees this annotation, is inject the component directly in the Servlet, Java Class, Managed Bean, whatever. (In JBoss this annotation has not been implemented yet, so you must use JNDI to call a remote component).

The @EJB annotation gets inside the attribute and can be used directly in the code. The code from Servlet looks like below:


package servlets;

import java.io.*;

import javax.ejb.EJB;
import javax.servlet.*;
import javax.servlet.http.*;
import stateless.TestEJBRemote;

public class TestServlet extends HttpServlet {

    //This annotation INJECTS the TestEJBRemove object from EJB into this attribute
    @EJB
    private TestEJBRemote testEJB;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println(testEJB.getMessage());
    }
}

Look at the line #13. It has the @EJB annotation. Also, look at the body of doGet method. No JNDI method was used, no code to call the EJB object was used, thus the code gets much clear than JNDI (Point to Glassfish over JBoss :) ).

Running the code

You can run the application right click on EAR project (in my case Test) and select option Run. Netbeans will do the deploy automatically and when the glassfish is started, the index.jsp page will be opened in your web browser.

After that, click on the LINK and see in the console of Netbeans (tab Glassfish) to see the output.

Note: Although the @EJB annotation is much better than JNDI calls, it only works in the Glassfish server environment. Therefore if you are creating a stand-alone application that calls a remote object, you CANNOT use the @EJB annotation.

Creating a Java Stand-Alone Client

As mentioned above, you cannot use the @EJB annotation out of a Glassfish server environment, therefore in a Stand-Alone application you must use the JNDI. Below following an example of how to call a EJB from a Java Stand-Alone client.

First of all, create a Java Project. New Project -> Java -> Java Application.

In this application, you must add two JARs file, as well as associate your application with the EJB module (thus your client knows about the EJB Interface).

To do that, right click on Java Project, Properties -> Libraries -> Add Project (to add the Test project) and Add JAR/Folder to add the following jar files:

  1. appserv-rt.jar
  2. javaee.jar

Both jar can be located into $GLASSFISH_HOME/lib directory.

By default, the appserv-rt.jar brings a jndi.properties file, but I will show you how to create one. Why? Because when you are running the client in the machine different than the app server, you must override this file.

So create a file called jndi.properties file into the root of the Java project and put the following content:


java.naming.factory.initial = com.sun.enterprise.naming.SerialInitContextFactory
java.naming.factory.url.pkgs = com.sun.enterprise.naming
java.naming.factory.state = com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl
#optional.  Defaults to localhost.  Only needed if web server is running
#on a different host than the appserver
org.omg.CORBA.ORBInitialHost = localhost
#optional.  Defaults to 3700.  Only needed if target orb port is not 3700.
org.omg.CORBA.ORBInitialPort = 3700

Now, open the main class and add the following commands:


package testclient;

import java.io.FileInputStream;
import java.util.Properties;
import javax.naming.InitialContext;
import stateless.TestEJBRemote;

public class Main {

    public static void main(String[] args) throws Exception {
        Properties props = new Properties();
        props.load(new FileInputStream("jndi.properties"));
        InitialContext ctx = new InitialContext(props);
        TestEJBRemote testEJB = (TestEJBRemote) ctx.lookup("stateless.TestEJBRemote");
        System.out.println(testEJB.getMessage());
    }
}

Save it and before run this code, make sure the Glassfish is running. After you run the java class, you should see the EJB message onto the console.

This topic overs here. I hope this topic be useful for anyone, as well as you can choose yourself which environment (Eclipse or Netbeans) is better for you.

On the next topic, I will show you how to configure Glassfish on Eclipse Europa and create a Statefull object.

Posted in Java | Tagged: , , , | 9 Comments »

Example of EJB3 (Session Bean) using Eclipse Europa and JBoss

Posted by jrjuniorsp on April 25, 2008

After the frustration of EJB 2, EJB 3 is growing in the community every day.

Different from EJB 2, EJB3 is simpler and much productive. However you have to pay attention before work with EJB3.

First of all, you have to make sure that your Production environment has Java 5 version, as well as your Application Server is JEE 5-compliance. Many servers do not have this configuration yet. (I myself work in a project that uses J2EE 1.4).

Also, EJB 3 does not need to be used in ALL applications. You have to think if in your project EJB is really necessary. In general, EJB are used when you need of distributed components.

JBoss is one of the most popular open-source Application Server and its version 4.2 supports JEE 5. Glassfish from Sun is also another good choice for free application server.

In this topic I am going to show you a simple example of how to create a Session Bean using Eclipse Europa and JBoss Application Server. If you do not have the JBoss AS installed, you can check this topic to install it.

After install Java 5 or 6, JBoss AS and Eclipse Europa, it is time to create the application itself. Let’s open the Eclipse and prepare our developer skill :)

Configuration JBoss within Eclipse Europa

Inside the Eclipse Europa, open the Servers view (Window -> Show View -> Servers). Right mouse click on Servers view and choose option New -> Server.

Choose the JBoss 4.2 and its path. After that the JBoss server should appear on the Servers view.

Creating the Enterprise Application Project

On Eclipse IDE (Using the Java EE perspective), right mouse click on Package Explorer and go to New -> Enterprise Application Project.

Choose the Project Name (e.g: TestApplication), Target Runtime (JBoss 4.2) and click on Next button.

On the next screen keep the EAR checked and click on Next. On the third screen, click on New Module button to select the modules you want to install. Let’s work on with two modules (EJB and Web). Choose these modules and click OK. Also, on third screen mark the option Generate Deployment Descriptor.

After that, the Enterprise Application Project will be created, as well as the EJB and Web modules. All of them can be reached in the Package Explorer.

Creating our first EJB component (Stateless Session Bean)

In Eclipse Europa, there is not an option to create a EJB component itself. You have to do it manually. However in the new EJB version, you can use Annotations rather than a Deployment Descriptor (XML) to map your components. As the annotation is much easier than XML, you will not loose productive in the component development.

Remember: In EJB 3 you need only two files: an Interface (local or remote) and its implementation. By default, the interface receives the name of the component and the implementation receives the name of the component plus Bean.

The first think to do is to create our Interface. In your example, we are going to use a simple Session Bean which has one method (public void getMessage). So creates this interface inside the EJB project. Right mouse click on TestApplicationEJB -> New -> Interface.

Also, put the method public String getMessage(); into this interface.


package lesson.stateless;
public interface HelloWorld {
	public String getMessage();
}

The next step is to create the class that implements this interface. The pattern is the class has the same name than the interface plus Bean.

To create a click, right mouse click on TestApplicationEJB -> New -> Class. Insert the class name and choose the Interface.

Note: As the interface calls HelloWorld, than our class calls: HelloWorldBean.

Now it is time to implement the HelloWorldBean.java class. It is a simple class which contains only one method. Look at its implementation below:


package lesson.stateless;

import javax.ejb.Remote;
import javax.ejb.Stateless;

@Stateless
@Remote(HelloWorld.class)
public class HelloWorldBean implements HelloWorld {
    public String getMessage() {
        return "Hello EJB World";
    }
}

Pay attention on line 6 and 7. The @Stateless annotation tells to the AS which the component is a Stateless Session Bean. Also, the @Remote annotation tells to the AS which interface is the remote for this implementation.

Done! Our EJB module is done to be deployed. If you are coming from EJB 2, you can see how the EJB 3 is much easier and productive :)

Using the Web Module as EJB Client.

It is common you have in the same EAR a EJB Module and a Web Module. In this case, the Web module works as a EJB Client, in other words, the We Module is going to be the FRONT-END as long as the EJB Module is going to be the BACK-END.

In our example we will use a simple Web Module. A single JSP file that call a servlet. The servlet makes connection with the EJB Module and print out in the console the message from EJB.

First of all, let’s create the JSP file. Expand the TestApplicationWeb and right click on WebContent -> New -> JSP. Create a jsp with the name index. Inside the JSP, put a call to the servlet. Let’s call our servlet as TestServlet. The JSP content could be anything like this:


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<body>
    <h1>Web Module used as EJB Client</h1>
    <a href="TestServlet">Click here to call the EJB component</a>
</body>
</html>

Now it is time to create the Servlet component. Right mouse click on TestApplicationWeb -> New -> Servlet. Put the name TestServlet and choose a package (if you want).

Before implement this method, we need to create a binding between the Web Module and the EJB Module. To do that right mouse click on TestApplicationWeb -> Properties.

Go to J2EE Module Dependencies and mark the option TestApplicationEJB.jar. Thus your Web module will see the EJB interfaces, but remember, you cannot call it directly.

Now we are able to implement the servlet. We are going to use only the method doGet (fell free to get rid of the doPost method). Inside the doGet method, we are going to call the EJB component and show its return message.


package lesson.servlets;

import java.io.IOException;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import lesson.stateless.HelloWorld;

public class TestServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
    static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            InitialContext ctx = new InitialContext();
            HelloWorld hello = (HelloWorld) ctx.lookup("TestApplication/HelloWorldBean/remote");
            System.out.println(hello.getMessage());
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }
}

Check out the lines 18 to 20.

  • In the line 18, we start an InitialContext object. As we are working inside the same EAR than the EJB, we cannot pass none parameter for its constructor. In the next example (Creating a Java stand-alone client), you will see that a Properties file is required.
  • In the line 19 we call the remote object HelloWorld. Pay attention on its JNDI name. The JBoss pattern is: First the EAR name / The EJB Implementation Component / remove or local. The ctx.lookup method looks for the remote object inside the EJB module and returns its instance.
  • In the line 20 we prints out the return of the getMessage() method.

Note: The annotation @EJB does not work properly in JBoss server. If anyone had success using this annotation, please let me know :).

Now you can run this application. Right mouse click on TestApplicationWeb -> Run As -> Run on Server. The first time you try to run the application, a screen regarding server configuration will come up. Select the JBoss 4.2 server (you previosly configurated) and mark the option Always use this sever when running this project. Click OK and the server will starts.

Inside the Eclipse you will see the web page. Click on the link and look at the Eclipse Console. A message from EJB should appears for you.

Creating a Java Stand-Alone Client

You should use EJB when you need of distributed components. Besides use distributed components in the server (through clustering, SOA, and so on), you can create a communication between a Stand-Alone application.

A Stand-Alone application calls the EJB in a similar way then Web Modules, however it has some particularities.

  1. You have to import some JBoss libraries to the stand-alone application
  2. You have to create a Properties file and use it in the InitialContext object
  3. The Stand-Alone application must “know” the remote components interfaces.

Create a Java Project, File -> New -> Project -> Java Project.

Import the following two files to this project


jbossall-client.jar
jboss-ejb3-client.jar

You can find these files inside $JBOSS_HOME/client directory. To add them to the Project classpath, right click on Java Project -> Propeties. Go to Java Build Path -> Libraries -> Add External JARs.

Also, inside the Properties screen, click on Projects tab and then Add button. Select the EJB module. This way your client application will see the remote ejb object.

Create a properties file (called jndi.properties) in the root of the Client project. The content of the file is below:


java.naming.factory.initial     = org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs     = org.jboss.naming:org.jnp.interfaces
java.naming.provider.url        = localhost:1099

Now create a simple Java class containing the void main (String args[]) method.

Implement this method, using the Properties file previously created as argument to InitialContext object.


package lesson.client;

import java.io.FileInputStream;
import java.util.Properties;

import javax.naming.InitialContext;

import lesson.stateless.HelloWorld;

public class TestClient {

    public static void main(String[] args) throws Exception {
        Properties props = new Properties();
        props.load(new FileInputStream("jndi.properties"));
        InitialContext ctx = new InitialContext(props);
        HelloWorld hello = (HelloWorld) ctx.lookup("TestApplication/HelloWorldBean/remote");
        System.out.println(hello.getMessage());
    }
}

Before run the client application, make sure the Application Server is running. If so, runs your Main class and see the output in the Eclipse Console view.

This topic ends here. I hope this topic can help the people who wants to work with EJB in Eclipse Europa. The next topic is the same example, but using Netbeans 6.1 and Glassfish. I hope you enjoy it.

Posted in Java | Tagged: , , , , , | 35 Comments »

Installing JBoss Application Server 4.2.x on Linux

Posted by jrjuniorsp on April 25, 2008

In this topic I am going to show you how to install the JBoss Application Server 4.2.x on a Linux station. Although my official Linux distribution is Ubuntu 7.10, you can use the same approach to install the JBoss AS in any Linux distribution (I’ve tested in Slackware 12 and worked fine).

Similar than Tomcat, JBoss installation is very easy.

Basically you have to download and unzip the file, as well as create an Environment Variable.

Downloading JBoss AS 4.2.x

You can get JBoss AS directly from its official website. When I wrote this topic, the latest stable version was: 4.2.2.GA.

You have two choices to download: Source and Binary files. I advice you the binary files because it is easier to install (and I will cover only the binary installation). If you prefer the source file, take a look at its official documentation to figure out how to compile and install the source file.

Installing JBoss

After you get the binary file (a .zip file), you have to unzip it. It is your choice where you will unzip the file. In my workstation, I’ve a folder called java inside my home space where I put all programs java related.

Unzipped the file, it is time to create an environment variable. Different than TOMCAT, JBoss requires only one environment variable called JBOSS_HOME. It must point to the JBoss folder previously unzipped.

Edit the ~/.bashrc file and put the following line in the bottom of the file (supposing the JBoss was unzipped in a folder called /home/your_user/java/jboss-4.2.2.GA


export JBOSS_HOME=/home/jair/java/jboss-4.2.2.GA

Save the file and re-logon your user.

Running JBoss

Enter into JBOSS_HOME/bin directory (cd $JBOSS_HOME/bin) and run the run.sh file (./run.sh).

The JBoss should be started without errors.

To test if the JBoss has been started, try out the following link: http://localhost:8080

You should see the Welcome to JBoss screen.

I hope this topic be useful for anyone.

Posted in Java, Linux | Tagged: , , , | No Comments »

Using associations (belongs_to, has_many) in Ruby on Rails.

Posted by jrjuniorsp on April 4, 2008

Probably you already needed or you will need in the future to create associations between the models in Ruby on Rails.

As you know, Rails uses the ActiveRecord as ORM. The ORM is responsible for the associations. Fortunately in Rails it is a simple task.

In this topic I am going to show you how to create the associations many-to-one (the most common).

Understanding the association

Create relationship between models in a common task in any application. Let’s take a look at the example below:

diagram1.png

A State can have many cities, e.g: NY state has: New York City, Rochester, Buffalo, Albany and so on.
A City belongs to only a single State, e.g: San Diego belongs to CA.

This is a relationship known as many-to-one. Note the state_id field in the Cities table. Each city belongs to only a single State, so you must save the ID of the State into the Cities table. it does make sense, doesn’t it?

Creating a simple application to see how the association does work

Using the model above, let’s create a simple application that show up all the Cities and their States. Also, let’s create a functionality to add new cities (not new states).

First of all, let’s create the rails project. Simply type the following:

rails RailsAssociation --database=mysql

Change the config/database.yml file according to your database configuration.

Now let’s create both model (State and City).

State

ruby script/generate model state name:string

City

ruby script/generate model city name:string state_id:integer

We are going to use only one field for each model. Note: in the City model we’ve got a state_id field.
Remember: Although the model names are state and city, the table name will be states and cities.

Now let’s run the rake and create the tables physically into the database.

rake db:migrate

Let’s add some values into the database directly. (We are not cover in this topic how to create the NEW functionality to states).

INSERT INTO states (name) values ('NY');
INSERT INTO states (name) values ('CA');
INSERT INTO cities (name, state_id) values ('New York City',1);
INSERT INTO cities (name, state_id) values ('Buffalo',1);
INSERT INTO cities (name, state_id) values ('San Jose',2);
INSERT INTO cities (name, state_id) values ('Rochester',1);
INSERT INTO cities (name, state_id) values ('San Francisco',2);

What has been done? Well, we added two states (NY and CA) and also we added 5 citie, 2 belong to CA and 3 belong to NY.

Now it is time to create the controller and the views. Actually let’s create two views: new and list

ruby script/generate controller cities new list

Inside the cities controller, put the following code in the list method

def list
@cities = City.find(:all)
end

It simply fetch all cities from the database and put them in a @cities variable.

On the view, put the following in the file app/views/cities/list.html.erb

<h3>List of the cities</h3>
<% for city in @cities %>
<%= h(city.name) %> - <%= h(city.state.name) %><br />
<% end %>

Let’s pay attention on the lines above. We are iteration over the @cities variable and showing its content on the screen. Check it out the h(city.name) and h(city.state.name). The first is going to show the city’s name and the second the city state’s name. But wait a moment!! How does rails know the city.state.name? Where the state attribute was declared?

We must change the model to make the associations. So far rails doesn’t know nothing about the associations, but with few lines it will does.

Open the app/model/state.rb file and put the following:

has_many :cities

You just informed to Rails with a State has many cities. It’s simple, huh?

Now open the city.rb and add

belongs_to :state

Hey look at the code above!!! the :state attribute was declared there!! Now rails knows about the city.state.name. Rails is magic, isn’t it?

Now run the server ruby script/server and enter in the following url: http://localhost:3000/cities/list, you should see a screen like this:

assoc1.png

We’ve got the list functionality done, now let’s create the add. Open the file app/views/cities/add.html.erb and add the following content:

<h3>New City</h3>
<% if flash[:notice] %>
<p><%= h(flash[:notice]) %></p>
<% end %>
<% form_for :city do |form| %>
Name: <%= form.text_field :name %><br/>
state: <%= form.collection_select :state_id ,@states,:id,:name %><br/>
<%= submit_tag “Save” %>
<% end %>
<%= link_to “List”,:action => :list %>

As as normal form, we have two fiels (a text_field and a drop-down).

Now open the controller cities and implement the method new with the following content:

def new
if request.post?
@city = City.new(params[:city])
if @city.save!
flash[:notice] = “City has been saved successfully”
else
flash[:notice] = “Error saving the city. Contact support”
logger.error(”Error saving the city”)
end
end
@states = State.find(:all)
end

Nothing different, huh?

Try to run the application again and enter in the URL: http://localhost:3000/cities/new

You can download this simple application here. Remember to change the config/database.yml before run the server.

Posted in Ruby | Tagged: , , , , | No Comments »