Helidon MP Data Source Guide

This guide shows how to configure and use named DataSources in your Helidon MP application.

What You Need

For this 20 minute tutorial, you will need the following:

A Helidon {upper-case-flavor} ApplicationYou can use your own application or use the Helidon {upper-case-flavor} Quickstart to create a sample application.
Java SE 11 (Open JDK 11)Helidon requires Java 11+.
Maven 3.6.1+Helidon requires Maven 3.6.1+.
Docker 18.09+You need Docker if you want to build and deploy Docker containers.
Kubectl 1.16.5+If you want to deploy to Kubernetes, you need kubectl and a Kubernetes cluster (you can install one on your desktop).
curl(Optional) for testing
Verify Prerequisites
java -version
mvn --version
docker --version
kubectl version --short
Copied
Setting JAVA_HOME
# On Mac
export JAVA_HOME=`/usr/libexec/java_home -v 11`

# On Linux
# Use the appropriate path to your JDK
export JAVA_HOME=/usr/lib/jvm/jdk-11
Copied

Overview

By following this guide you’ll enhance a bare-bones Helidon MP application to access an in-memory H2 database database. You’ll see how to install the relevant dependencies, set up and configure the datasource, and add datasource-related code to your application.

Use the Maven Archetype to Generate a Helidon MP Application

In a shell, cd into an empty directory and run this:

mvn -U archetype:generate \
    -DinteractiveMode=false \
    -DarchetypeGroupId=io.helidon.archetypes \
    -DarchetypeArtifactId=helidon-bare-mp \
    -DarchetypeVersion=2.6.14 \
    -DgroupId=io.helidon.example \
    -DartifactId=helidon-ds \
    -Dpackage=io.helidon.example.ds
Copied

Now cd into helidon-ds. The rest of this guide will assume all relative paths are relative to this directory.

Add the H2 Database Driver to the Runtime Classpath

Add the following dependency in your pom.xml:

pom.xml
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
</dependency>
Copied

In a production application, you may use a different database, so in that case you may add a different database driver dependency here instead.

Add the Hikari Connection Pool Extension to the Runtime Classpath

Add the following dependency in your pom.xml:

pom.xml
<dependency>
    <groupId>io.helidon.integrations.cdi</groupId>
    <artifactId>helidon-integrations-cdi-datasource-hikaricp</artifactId>
    <scope>runtime</scope>
</dependency>
Copied

Add an application.yaml File With Database Connectivity Information

Replace the contents of the following file under src/main/resources:

src/main/resources/application.yaml
server:
    port: 8080
javax:
    sql:
        DataSource: 
            test: 
                dataSourceClassName: org.h2.jdbcx.JdbcDataSource 
                dataSource: 
                    url: jdbc:h2:mem:test 
                    user: sa
                    password: ""
Copied

Inject a Datasource into Your Application Code

In the src/main/java/io/helidon/example/ds/GreetResource.java file, add the following imports:

src/main/java/io/helidon/example/ds/GreetResource.java
import javax.enterprise.context.Dependent;
import javax.inject.Inject;
import javax.inject.Named;
import javax.sql.DataSource;
Copied

Annotate the resource class declaration with @Dependent:

src/main/java/io/helidon/example/ds/GreetResource.java
@Path("/greet")
@Dependent 
public class GreetResource {
Copied
  • This ensures that io.helidon.example.jpa.GreetResource is a discoverable CDI bean.

Then add the following annotated field declaration:

src/main/java/io/helidon/example/ds/GreetResource.java
@Inject 
@Named("test") 
private DataSource testDataSource;
Copied
  • The @Inject annotation is used to indicate that the CDI container should set the annotated field automatically.
  • The @Named annotation is used to select which data source should be injected. Here, the test data source is requested.

Use The Injected DataSource

Now that you have a DataSource, you’ll use it to connect to the database.

First, ensure the io.helidon.example.ds.GreetResource resource class imports various java.sql classes:

src/main/java/io/helidon/example/ds/GreetResource.java
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
Copied

Add the following resource method to the GreetResource class:

src/main/java/io/helidon/example/ds/GreetResource.java
@GET
@Path("tables")
@Produces("text/plain")
public String getTableNames() throws SQLException { 
    StringBuilder sb = new StringBuilder();
    try (Connection connection = this.testDataSource.getConnection(); 
         PreparedStatement ps =
           connection.prepareStatement(" SELECT TABLE_NAME" 
                                       + " FROM INFORMATION_SCHEMA.TABLES "
                                       + "ORDER BY TABLE_NAME ASC");
         ResultSet rs = ps.executeQuery()) {
      while (rs.next()) {
        sb.append(rs.getString(1)).append("\n");
      }
    }
    return sb.toString();
}
Copied
  • Database interactions can throw SQLException.
  • We acquire a Connection, a PreparedStatement and a ResultSet in a try-with-resources block.
  • This SQL statement returns a list of all table names in the database.

Build the Application

Execute the following from the root directory of your application:

mvn clean package
Copied

Run the Application

Execute the following from the root directory of your application:

java -jar target/helidon-ds.jar
Copied

Test the Application

Execute the following:

curl http://localhost:8080/greet/tables
Copied

Observe that the result will be a list of database table names.

Helidon features a few examples of projects that use datasources.

Some examples' configurations can be found in their META-INF/microprofile-config.properties resources instead of in an application.yaml file as described above. Though the syntax is different, the same principles as those described above still apply.