I just announced the new Spring 5 modules in REST With Spring:

>> CHECK OUT THE COURSE

1. Introduction

ActiveJDBC is a lightweight ORM following the core ideas of ActiveRecord, the primary ORM of Ruby on Rails.

It focuses on simplifying the interaction with databases by removing the extra layer of typical persistence managers and focuses on the usage of SQL rather than creating a new query language.

Additionally, it provides its own way of writing unit tests for the database interaction through the DBSpec class.

Let’s see how this library differs from other popular Java ORMs and how to use it.

2. ActiveJDBC vs Other ORMs

ActiveJDBC has stark differences compared to most other Java ORMs. It infers the DB schema parameters from a database, thus removing the need for mapping entities to underlying tables.

No sessions, no persistence managers, no need to learn a new query language, no getters/setters. The library itself is light in terms of size and number of dependencies.

This implementation encourages the usage of test databases which are cleaned up by the framework after executing the tests, thus reducing the cost of maintaining test databases.

However, a little extra step of instrumentation is needed whenever we create or update model. We’ll discuss this in coming sections.

3. Design Principles

  • Infers metadata from DB
  • Convention-based configuration
  • No sessions, no “attaching, re-attaching”
  • Lightweight Models, simple POJOs
  • No proxying
  • Avoidance of Anemic Domain Model
  • No need of DAOs and DTOs

4. Setting Up the Library

A typical Maven setup for working with a MySQL database includes:

<dependency>
    <groupId>org.javalite</groupId>
    <artifactId>activejdbc</artifactId>
    <version>1.4.13</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.34</version>
</dependency>

The latest version of activejdbc and mysql connector artifacts can be found on the Maven Central repository.

Instrumentation is the price of simplification and needed when working with ActiveJDBC projects.

There’s an instrumentation plugin which needs to be configured in the project:

<plugin>
    <groupId>org.javalite</groupId>
    <artifactId>activejdbc-instrumentation</artifactId>
    <version>1.4.13</version>
    <executions>
        <execution>
            <phase>process-classes</phase>
            <goals>
                <goal>instrument</goal>
            </goals>
        </execution>
    </executions>
</plugin>

The latest activejdbc-instrumentation plugin can also be found in Maven Central.

And now, we can process instrumentation by doing one of these two commands:

mvn process-classes
mvn activejdbc-instrumentation:instrument

5. Using ActiveJDBC

5.1. The Model

We can create a simple model with just one line of code – it involves extending the Model class.

The library uses inflections of the English language to achieve conversions of plural and singular forms of nouns. This can be overridden using the @Table annotation.

Let’s see how a simple model looks like:

import org.javalite.activejdbc.Model;

public class Employee extends Model {}

5.2. Connecting to a Database

Two classes – Base and DB – are provided to connect to databases.

The simplest way to connect to a database is:

Base.open("com.mysql.jdbc.Driver", "jdbc:mysql://host/organization", "user", "xxxxx");

When models are in operation, they utilize a connection found in the current thread. This connection is put on the local thread by the Base or DB class before any DB operation.

The above approach allows for a more concise API, removing the need for DB Session or Persistence managers like in other Java ORMs.

Let’s see how to use the DB class to connect to a database:

new DB("default").open(
  "com.mysql.jdbc.Driver", 
  "jdbc:mysql://localhost/dbname", 
  "root", 
  "XXXXXX");

If we look at how differently Base and DB are used to connect to databases, it helps us conclude that Base should be used if operating on a single database and DB should be used with multiple databases.

5.3. Inserting Record

Adding a record to the database is very simple. As mentioned before, there’s no need for setters and getters:

Employee e = new Employee();
e.set("first_name", "Hugo");
e.set("last_name", "Choi");
e.saveIt();

Alternatively, we can add the same record this way:

Employee employee = new Employee("Hugo","Choi");
employee.saveIt();

Or even, fluently:

new Employee()
 .set("first_name", "Hugo", "last_name", "Choi")
 .saveIt();

5.4. Updating Record

The snippet below shows how to update a record:

Employee employee = Employee.findFirst("first_name = ?", "Hugo");
employee
  .set("last_name","Choi")
  .saveIt();

5.5. Deleting Record

Employee e = Employee.findFirst("first_name = ?", "Hugo");
e.delete();

If there is a need to delete all records:

Employee.deleteAll();

If we want to delete a record from a master table which cascades to child tables, use deleteCascade:

Employee employee = Employee.findFirst("first_name = ?","Hugo");
employee.deleteCascade();

5.6. Fetching a Record

Let’s fetch a single record from the database:

Employee e = Employee.findFirst("first_name = ?", "Hugo");

If we want to fetch multiple records, we can use the where method:

List<Employee> employees = Employee.where("first_name = ?", "Hugo");

6. Transaction Support

In Java ORMs, there is an explicit connection or a manager object (EntityManager in JPA, SessionManager in Hibernate, etc.). There’s no such thing in ActiveJDBC.

The call Base.open() opens a connection, attaches it to the current thread and thus all subsequent methods of all models reuse this connection. The call Base.close() closes the connection and removes it from the current thread.

To manage transactions, there are are few convenience calls:

Starting a transaction:

Base.openTransaction();

Committing a transaction:

Base.commitTransaction();

Rolling back a transaction:

Base.rollbackTransaction();

7. Supported Databases

The latest version supports databases of likes SQLServer, MySQL, Oracle, PostgreSQL, H2, SQLite3, DB2.

8. Conclusion

In this quick tutorial, we focused on and explored the very basics of ActiveJDBC.

As always, the source code related to this article can be found over on Github.

I just announced the new Spring 5 modules in REST With Spring:

>> CHECK OUT THE LESSONS

newest oldest most voted
Mike Golod
Guest
Mike Golod

As I understand there is no type safety. So how can I be sure that my models still work? Write tests on every model I suppose? And more interesting question: how to integrate ActiveJDBC and Spring (with transaction support)?

Loredana Crusoveanu
Editor

Hey Mike,

The library does have the option of adding explicit getters and setters if you want. I can’t find any info about a Spring integration in their documentation. May be worth looking into it more.

Basanta Hota
Guest
Basanta Hota

Thanks for sharing such a wonderful concept but am facing one issue i followed same as per your above blogs , but data not inserting to DB , am not able to find root cause can you please help me out on same

Basanta Hota
Guest
Basanta Hota

Hi Team ,
Thanks issue got resolved instead of use saveIt() use insert() it will work .
Important! insert is not available on old version, so use 1.4.7 or higher

Loredana Crusoveanu
Editor

Hey Basanta,

Glad to hear you solved your issue. The way the saveIt() method works is by checking whether the object has an id or not. If the id is null, then it triggers an INSERT. If the id is not null, then it tries to do an UPDATE. So if you’re setting the id manually, then you have to use the insert() method.

More info here: http://javalite.io/surrogate_primary_keys#override-standard-key-value-behavior

Basanta Hota
Guest
Basanta Hota

Thanks for your update