Skip to content

POJO based Persistence

Alessio Stalla edited this page Feb 15, 2022 · 2 revisions

Starting from Portofino 5.2, we can map database tables to Plain Old Java Objects (POJOs).

Portofino has always used map-based persistence, as maps are convenient to use in Groovy because of simple syntax and dynamic typing. However, since the IDE has no way of checking them for correctness, typos and type errors may remain undetected until runtime. This happens especially when some data type changes in the model (e.g., from int to long) and suddenly your CRUD pages break – with little information to track the error down. By mapping database tables to POJOs (Plain Old Java Objects) these problems are no longer relevant.

We can make the choice between maps and POJOs separately for each database.

How does it work?

In Portofino 5.1.0, we migrated from Hiberate 4, which was no longer actively developed, to Hibernate 5. As part of this effort, we replaced the old ad-hoc code we used to configure Hibernate 4 programmatically, and we resorted to generating annotated classes at runtime. For each database table, Portofino creates a Java class under the hood, with a property for each column and relationship, fully annotated for Hibernate.

From that, it's a natural progression to expose those runtime-generated classes to user code. So, from Portofino 5.2, we have the option to use instances of such classes to map our data to the database, instead of Java hash maps.

Migrating from Maps to POJOs

We can change the mapping scheme at any time from the "Connections" page upstairs.

Since Groovy is dynamically typed, and the syntax for accessing maps and objects is the same, switching from maps to POJOs often doesn't have any impact on existing code. However, code that makes explicit use of maps – for example, to create a copy of an object – needs to be adapted if we want to change to POJO-based persistence, on a case-by-case basis.

Also, pay attention to Security.groovy. The version generated by Portofino 5.2 or newer supports POJOs out of the box. However, if Security.groovy was generated with an older version of Portofino, we'll have to update it, either re-running the wizard or editing it by hand.

IDE Support

To map database tables, Portofino generates classes at runtime. So, our IDE doesn't know anything about those classes; they're not among the sources or the dependencies of the project.

To aid us in writing code with good IDE support, Portofino will dump runtime-generated classes to directory WEB-INF/classes-generated inside the running application. For example, when launching an application as an IntelliJ IDEA project, the path will be target/<name>-<version>/WEB-INF/classes-generated. Then, we can point our IDE to that directory to have it index the classes that we'll use for persistence.

If we launch the application in a Docker container, the directory will be inside the container, and we'll have to manually copy the files outside of it if we want our IDE to pick them up. Remember that they change every time we change the model or synchronize it with the database.