EJB 2 – Entity EJB on database view
Entity EJB with EJB 2 on a database view
This tutorial explain how you create an
Entity EJB which shows a database view. The
advantage is that you can achieve a very high performance as you can
optimize your view query in SQL.
General
Author:
Sascha
Wolski
Sebastian
Hennebrueder
Date: April, 6 2005
Software:
Eclipse
3.x
MyEclipse
3.8.x or xDoclet
Downloads
PDF:
http://www.laliluna.de/download/ejb-on-database-view-en.pdf
Sources:
http://www.laliluna.de/download/ejb-on-database-views-source.zip
What
are database views
Database
views are saved queries (views) in the database of object tables.
They are write protected and can access like a normal database table.
You can use a database view to provide selections of data, that can
not be modified.
The
advantage is that you can achieve a very high performance as you can
optimize your view query in SQL.
(There
are some advanced databases where you can even update a view or where
they are not only queries but real database entries.)
Create the EJB project
Let’s start. Create a new EJB project and
name it DatabaseViewEjb.

Configure xDoclet
Right click on the project and choose
Properties (Alt + Enter).
Choose
MyEclipse-XDoclet and click on Standard EJB.

In the window
below right click and choose Add.
Choose jboss
from the list.

Select jboss
on the list and add the xDoclet settings.


Close the
property window of the project.
Notice: dataSourceMapping and
datasource:
Have a look in the basic EJB tutorials
http://www.laliluna.de/articles/java-persistence-hibernate/simple-xdoclet-ejb-tutorial.html
to find more information on how to change the configuration for other
databases.
Create the entity bean
First create a new package
de.laliluna.tutorial.databaseview.entity.ejb.
Create a new
entity bean BookView. Right click on the project and choose
New > Entity Bean.

You
do not need to create the ejbCreate() and ejbPostCrearte()
method on an entity bean which refers to a view, because the view is
write protected and the methods are only needed to create new
entries.
The entity bean
will refers to a view vbook in our ejbexample database,
we will create later. The view contains two columns, id and
title.
Now lets look at
the xDoclet comments. We have to add some settings for the
entity bean class.
The following
source code shows the xDoclet class comments.
Define a value
object BookView.
Set the
jboss.persistence properties create-table and
remove-table to false, because jboss can`t create or
remove a view. The view is write protected, so set the
jboss.persistence property read-only to true.
Define a finder
findAll() which returns all entries of the view.
/**<br> * @author laliluna.de<br> * <br> * @ejb.bean name="BookView"<br> * display-name="Name for BookView"<br> * description="Description for BookView"<br> * jndi-name="ejb/BookView"<br> * type="CMP"<br> * cmp-version="2.x"<br> * view-type="local"<br> * primkey-field = "id"<br> * <br> * @ejb.util generate="physical"<br> * @ejb.persistence table-name = "vbook" <br> * @ejb.value-object match = "*" name="BookView" <br> * <br> * <span style="font-weight: normal;">@jboss.persistence create-table = "false" </span><br> * <span style="font-weight: normal;">remove-table = "false" </span><br> * <span style="font-weight: normal;">read-only = "true"</span><br> * <br> * <span style="font-style: normal;"><span style="font-weight: normal;">@ejb.finder description = "Find all"</span></span><br> * <span style="font-style: normal;"><span style="font-weight: normal;">signature = "java.util.Collection findAll()"</span></span><span style="font-style: normal;"><b> </b></span><br> * <span style="font-style: normal;"><span style="font-weight: normal;">query = "select object(c) from BookView as c"</span></span><br> * <br> * <br> */
Now create the
getter and setter methods for the two columns, fid and ftitle,
of the view.
/
* @ejb.interface-method view-type = “local”
* @ejb.persistence column-name = “fid”
*
* @ejb.pk-field
*
*
* @return
*/
public abstract Integer getId();
/
* @ejb.interface-method view-type = “local”
* @param id
/
public abstract void setId(Integer id);
/
* @ejb.interface-method view-type = “local”
* @ejb.persistence column-name = “ftitle”
*
* @return
*/
public abstract String getTitle();
/
* @ejb.interface-method view-type = “local”
* @param title
*/
public abstract void setTitle(String title);
Note:
Its recommend to run
xDoclet first time to generate the interface classes. Right
click on the project and choose MyEclipse > Run xDoclet.
Lets provide a getter and setter method for
the generated value object.
/
* @ejb.interface-method view-type = “local”
* @return
*/
public abstract BookViewValue getBookViewValue();
/
* @ejb.interface-method view-type = “local”
* @param bookViewValue
*/
public abstract void setBookViewValue(BookViewValue bookViewValue);
Thats all, the entity bean for a view is
finished.
Create the session bean
Create a new package
de.laliluna.tutorial.databaseview.session.ejb
and create a new Session Bean BookViewSession.

Open the
session bean class and provide a method getAll(), which
returns a collection of BookViewValue objects.
The following source code shows the session
bean method getAll():
/*
* Return a collection of BookViewValue objects
*
* @ejb.interface-method view-type = “both”
*/
public Collection getAll() throws EJBException {
Collection collection = null;
try {
Context context = new InitialContext();
// get the local home
BookViewLocalHome localHome = (BookViewLocalHome) context
.lookup(BookViewLocalHome.JNDI_NAME);
// get all entries of the local home
Collection localCollection = localHome.findAll();
// fill the collection that will be returned
collection = new ArrayList();
for (Iterator iter = localCollection.iterator(); iter.hasNext();) {
BookViewLocal element = (BookViewLocal) iter.next();
collection.add(element.getBookViewValue());
}
} catch (FinderException e) {
e.printStackTrace();
} catch (NamingException e) {
e.printStackTrace();
}
return collection;
}
That’s all for the session bean class.
Note:
Run xDoclet to
generate the session bean interface classed. Right click on the
project and choose MyEclipse > Run xDoclet.
Provide the database view
Create a new database ejbexample with
your favorite Postgre manager.
Provide a table tbook with two
columns fid of type serial and ftitle of type text.
The postgre-sql query for creating the table
looks like the following:
CREATE TABLE tbook
(
fid serial NOT NULL,
ftitle text
)
WITH OIDS;
Insert some dummy data for testing.
Create a view vbook for this table.
The postgre-sql query for the view looks
like the following:
CREATE OR REPLACE VIEW vbook AS
SELECT tbook.fid, tbook.ftitle
FROM tbook;
Datasource mapping file
Create a new datasource mapping file named
ejbexmaple-ds.xml and place it in the folder
../jboss-root/server/default/deploy/ to have access to the
database.
The content of the file looks like the
following:
<datasources>
<local-tx-datasource>
<jndi-name>ejbexample</jndi-name>
<connection-url>jdbc:postgresql://localhost:5432/ejbexample</connection-url>
<driver-class>org.postgresql.Driver</driver-class>
<user-name>postgres</user-name>
<password>pgsql</password>
</local-tx-datasource>
</datasources>
Note:
Deploy the EJB project to
the Jboss server.
Create the test client
Create a new Java project DatabaseViewClient
to test the EJB project.
Add a source folder src, right click
on the project and choose New > Source Folder.
Provide a package named
de.laliluna.tutorial.databaseview.
Add the EJB project on Projects to
access to the EJB classes.
Right click on the project and choose
Properties > Java Build Path.

You have to add the J2EE Library and the
following JBoss libraries to use a normal Java project for testing an
EJB project. If you like you can use the jboss-all-client.jar instead
of the single libraries.

The test class
Create a new Java class TestView in
the package de.laliluna.tutorial.databaseview.
We have to set some properties to lookup the
EJBs in the JNDI context of jboss. You can do this within the
constructor.
Create a method testEJB() where you
put the code for testing the EJB.
In the main(..) method you call the
testEJB() method.
The following source code shows the class
TestView:
public class TestView {
Properties properties;
public TestView() {
properties = new Properties();
properties.put(“java.naming.factory.initial”,
“org.jnp.interfaces.NamingContextFactory”);
properties.put(“java.naming.factory.url.pkgs”,
“org.jboss.naming:org.jnp.interfaces”);
properties.put(“java.naming.provider.url”, “jnp://localhost:1099”);
properties.put(“jnp.disableDiscovery”, “true”);
}
public static void main(String[] args) {
TestView testView = new TestView();
// call the testEJB method
testView.testEJB();
}
public void testEJB(){
try {
InitialContext context = new InitialContext(properties);
// get the session home interface
BookViewSessionHome sessionHome = (BookViewSessionHome) context
.lookup(BookViewSessionHome.JNDI_NAME);
// create a session object
BookViewSession session = sessionHome.create();
// output data
Collection collection = session.getAll();
for (Iterator iter = collection.iterator(); iter.hasNext();) {
BookViewValue element = (BookViewValue) iter.next();
System.out.print(element.getId() + ", ");
System.out.print(element.getTitle() + ", ");
}
} catch (CreateException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
} catch (NamingException e) {
e.printStackTrace();
}
}
}
That’s all for the testing class. Now you
can now run the class as java Application. Right click on the project
and choose Run > Java Application.