Introducing the DataSourceDefinition Annotation

One of the many cool new features in Java EE 6, is support for the DataSourceDefinition annotation.

The DataSourceDefinition annotation provides a way to define a DataSource and register it with JNDI. The annotation provided annotation elements for the commonly used DataSource properties. Additional standard and vendor specific properties may also be specified.

So let us look at an example:

@DataSourceDefinition(name = "java:global/MyApp/myDS",

className = "org.apache.derby.jdbc.ClientDataSource",

portNumber = 1527,

serverName = "localhost",

databaseName = "testDB",

user = "lance",

password = "secret",

properties = {"createDatabase=create"}) )

The data source will be registered using the value specified in the name element and can be defined in any valid Java EE name space and that will determine the accessibility of the data source from other components.

The properties element is used to specify less frequently used standard DataSource properties as well as vendor-specified properties using the format :

{"property1=value", "property2=value" ...}

Using the newly defined DataSource is as simple as:

  @Resource(lookup = "java:global/MyApp/myDS")
  private DataSource ds;

You can also define multiple DataSources using the DataSourceDefinitions annotation:

@DataSourceDefinitions({

@DataSourceDefinition(name = "java:global/MyApp/myDS",


className = "org.apache.derby.jdbc.ClientDataSource",

portNumber = 1527,

serverName = "localhost",

databaseName = "testDB21",

user = "lance",

password = "secret",

properties = {"createDatabase=create"}),

@DataSourceDefinition(name = "java:global/MyApp/myDS2",


className = "com.mysql.jdbc.jdbc2.optional.MysqlDataSource",

portNumber = 3306,

serverName = "localhost",

databaseName = "dogDB",

user = "luckyDog",

password = "shhh",

properties = {"pedantic=true"})

})

So let's look at a simple web application, DataSourceDefWebApp, which utilizes the DataSourceDefinition. The application is provided as a NetBeans project that was created with NetBeans 6.8.

The application when deployed, will create a DataSource for Java DB.

When you go to run the application, you will need to make sure that you have the Java DB client JDBC driver accessible to your appserver, which it will be for Glassfish V3 and the Java DB server started.

To run the application after you have deployed it, go to the following URL using your favorite browser:

http://:/DataSourceDefWebApp

When you first run the application, you will see the following menu. Select the menu option "Initialize the Database", to create the Java DB database and create two initial contacts.

After initializing the database you can select "Add a Contact" to add a new contact to your database.

When you click the "Add Contact", button you will be taken to the displayContacts page.

,  

The application defines the DataSource in the DataSourceDefServlet:

@DataSourceDefinition(name = "java:global/MyApp/myDS",
className = "org.apache.derby.jdbc.ClientDataSource",
portNumber = 1527,
serverName = "localhost",
databaseName = "testDB",
user = "lance",
password = "secret",
properties = {"createDatabase=create"})
@WebServlet(name = "DataSourceDefServlet", urlPatterns = {"/DataSourceDefServlet", "/displayContacts", "/addContact", "/initDB"})
public class DataSourceDefServlet extends HttpServlet {

private ServletContext context;
@Resource(lookup = "java:global/MyApp/myDS")
private DataSource ds;

The DataSourceDefinition annotation is specified above the class declaration. The Resource annotation is then used specifying the JNDI name that was defined in DataSourceDefinition.

The Stateless Session bean, DemoBean, also uses the Resource annotation to access the same DataSource via:

@Resource(lookup = "java:global/MyApp/myDS")
private DataSource ds;

You can also override the settings that you have specified in the DataSourceDefinition annotation by adding the data-source element to your web.xml. For example, in order to use a MySQL database instead of Java DB, you can create a web.xml and add the following (remember to adjust the properties as necessary):

    <data-source>

<description>DataSource for MySQL</description>
<name>java:global/MyApp/myDS</name>
<class-name>com.mysql.jdbc.jdbc2.optional.MysqlDataSource</class-name>
<server-name>localhost</server-name>

<port-number>3306</port-number>
<database-name>testDB</database-name>
<user>lance</user>
<password>secret</password>

<property>
<name>x</name>
<value>y</value>
</property>
<property>

<name>y</name>
<value>x</value>
</property>
<login-timeout>500</login-timeout>

<transactional>false</transactional>
<isolation-level>TRANSACTION_READ_COMMITTED</isolation-level>
<initial-pool-size>2</initial-pool-size>
<max-pool-size>5</max-pool-size>

<min-pool-size>1</min-pool-size>
<max-idle-time>500</max-idle-time>
<max-statements>100</max-statements>
</data-source>

In the top level directory of the DataSourceDefinitionWebApp, you will find a web.xml that you can move to the web/WEB-INF folder of the project. Adjust the properties for the data-source to correctly point to your MySQL database, then rebuild and deploy.

When you go to display the data, you will notice that the the output from displayContacts indicates thatthe database that is being used in MySQL

The DataSourceDefinition annotation is a simple yet powerful addition to Java EE 6. Enjoy!

References: