Getting started with Dropwizard: Connecting to a Database using Hibernate
Here is a link to my Getting Started with Dropwizard course on Udemy. Only $10!
In the previous installments of this series we discussed how to create a Dropwizard application using Maven archetype and how to use a YAML file to set configuration parameters for the application. In this tutorial we'll create a simple application that exposes an Employee Directory via REST API. For simplicity reasons our representations will not contain hyperlinks, that is we'll talk about Level 2 of Richardson Maturity Model. The sources for the tutorial can be found here.
We'll begin with adding parameters of database connection including credentials, connection URI and database driver name to the application's configuration file. The snippet below shows how to configure the database connection.
MySQL RDBMS was used for our example, but some other DBMS can be used. As we'll use Hibernate to talk to our database, switching databases is a snap, it's only necessary to change the name of the driver in the snippet above. The benefit of using Hibernate is that it knows how to work with different database management systems, and there is no necessity to change application's code after switching to a different RDBMS.Our next step would be changing pom.xml of the application. Dropwizard has JDBI and Hibernate modules which can be used to connect to a database, and both include the database module which is also part of Dropwizard, therefore by adding Hibernate module, we accomplish the bigger part of changes necessary to use database in our application. In addition, we should add a dependency on a database driver, MySQL one in our case. So, if you prefer some other RDBMS, don't forget to replace the driver dependency. A code snippet with all necessary dependencies is shown below.
Then, after the required dependencies were added, we can change the Configuration class, called DWGettingStartedConfiguration in the example application. The sets of related parameters are grouped into so-called factories. We should create a new field of DataSourceFactory type and add a getter for it and Dropwizard will deserialize all database connections settings from the config.yml file to the factory. Here is the code to be added to the Configuration class.
If you are new to Hibernate, it suffices for now to know that Hibernate is able to map Java classes to database tables, that is for our application we'll need an Employee class with all the fields, describing an employee and an employees table with columns to store the same data and Hibernate knows how to transmit data from fields to columns and vice versa. Enough talk, let’s create a table and a class. SQL script to create a table is shown below.
Now let's turn to the class.
It's a Plain Old Java Object in addition to fields containing a couple of constructors, the no-argument is required, equals() and hashCode() methods inherited from Object and getters and setters for all fields, which can be auto-generated by an IDE and are not shown here. Also, there are some annotations. The first, @Entity shows that this POJO is mapped to a table. The second, @Table, is used to supply the name of the table to which the POJO is mapped and is required only if the names of the class and the table differ as in our case: Employee/employees. The third, @Id, is used to mark the field that uniquely identifies the instance of the class and in our case will store the auto-generated by RDBMS primary key. And, finally, the @GeneratedValue annotation shows that we use auto-increment as the generation strategy and instructs Hibernate to read the generated key value from the database to id field after saving a new entity. Also, there is a @Column which is used only if the name of a field and related column name differ.
In addition, we'll need to decorate our entity with one more annotation - @NamedQuery, which contains a comma – separated list of named queries, each used to extract data from the database. A special Java Persistence Query Language (JPQL) is used to create queries, which resembles SQL, but works not with tables and rows, but with classes and entities. The couple of queries to extract the full list of employees and to search employees by name are shown above.
We used fully qualified class names in the names of the queries to prevent creating queries with the same names but for different entities. The second query contains the so-called named parameter and we'll see in a moment how to pass parameters to queries. Also it is possible to split returned by queries lists of objects into parts, or in other words to paginate the list.
To hide from the developers most of the intricacies of Using Hibernate, Dropwizard offers us an AbsractDAO class. We should create DAO classes which implement all the CRUD logic by extending this class. An example is shown here.
We relied on the inherited method namedQuery(), which returns objects of a class implementing Query interface, which, in turn, can be used to pass parameters to queries. Also we used the inherited list() method, which knows how to retrieve lists from database using JPQL queries and inherited get() method which is used to fetch entities by id.
The next leg of our journey will be to create a resource class which relies on the newly created DAO and returns JSON representations of separate employees and lists of employees. The code is shown below. Most parts should be familiar to you, if you’ve read the previous two articles in this series. The difference now is that our resource class contains a DAO as a field and a constructor to initialize it. The striking difference is the @UnitOfWork annotation that decorates the methods of the class. It is part of Dropwizard and is used to save developers from writing a lot of Hibernate-related boilerplate code.
Also a Dropwizard LongParam class should be mentioned, which is helpful in checking that the argument of the correct type was passed from the client. If the client tries to provide a string instead of long, 400 Bad Request response will be returned. Please note, that Dropwizard knows how to deal with Optionals, and 404 Not Found HTTP response code code will be returned to the client, if a method in the resource class returns an empty Optional.
And now we have to create a so-called Hibernate bundle – a new field in the Application class, called DWGettingStartedApplication in the example application. Please note, that a comma-separated list of all entity classes should be passed to the Hibernate bundle.
We have to add the bundle in the body of the Application's initialize() method and after that, it can be used later to produce instances of Hibernate ConnectionFactory objects. We won't go into the details of how the aforementioned factory works, due to the fact that Dropwizard uses it behind the scenes to perform CRUD operation and there is no necessity to dig deeper to start using Hibernate with Dropwizard.
Finally, we should register our resource class in the run() method of the Application class, but before that we have to create an instance of DAO and pass an instance of Hibernate session factory, obtained from Hibernate bundle, to it. The code snippet below shows how this could be accomplished.
We have created a simple resource class that can extract data from a RDBMS, using Hibernate and helpful classes offered by Dropwizard, and return JSON representations to the client. If you followed the series, you should be able to test the code using either cURL or a browser add-on. It can be seen that Dropwizard Hibernate module makes it extremely easy to create a RESTlike API that uses a database to store its data. If you would like to learn more about how to use Hibernate and database migrations in a Dropwizard project, you could take a look at my Getting Started with Dropwizard course on Udemy.