Introduction

With all the Java ORMs available, why was Squeryl written ?

Squeryl is a departure from standard Java ORMs, we hope that the following arguments will provide sufficient justification for not following the Java standards, all of the arguments presented apply equally to JPA, JDO or Hibernate.

JPA was designed to provide the maximum functionality and expressiveness within the constraints of the Java language. All of them escape the language with a string based query language (JPA-QL, JDOQL, HQL, etc…) for situations where their imperative APIs aren’t sufficient or yields poor performance. Squeryl does everything with a single language : Scala

Squeryl will have achieved something if one never has to define a database a query as a raw string.

HQL, JDOQL and JPA-QL queries are merely strings, and are therefore fragile

When a project has tens of thousands of lines of code, making changes to the ORM’s schema requires extensive impact analysis, one must browse through all string (whatever-QL) queries and verify if they are affected. With Squeryl statements, the compiler will list all breaking changes, and an IDEs can help you with the refactoring.

Here is a comparison of a Squeryl and a JPA version of the same query :

The equivalent JPA query invocation is subject to a runtime failure at five places :

String/annotation based queries inhibit reusability by not being composable

Reusability of code is a very desirable property. Many design patterns are beneficial because they increase reuse. The current generation of Java ORMs by using string expressions, annotations and XML don’t support composition of queries, making reuse difficult. A Squeryl query on the other hand, can be queried against as if it was a view or a table, so they only need to be defined once and can be reused as sub queries.

Current Java ORMs wrap a high level language (SQL) into a lower level API

A JPA style ORM expose an object model on which user code navigates from one entity to another via relations that are represented as collections. While this approach is adequate for simple cases it can lead to verbose imperative code and excessive round trips to the database, which is why they all have a (string based) query language (HQL, JPA-QL, etc..)

Explicitly control retrieval granularity and laziness

A significant part of optimizing a database abstraction layer is to choose for every situation the right balance between fine and large grained retrieval, and the optimal mix of laziness and eagerness. Data retrieval strategies are explicit in Squeryl rather than driven by configuration like current generation Java ORMs With Squeryl it is done explicitly, i.e. by reading a statement it is clear how much data it will fetch, and when it will occur.

Hibernate has extensive documentation on how to avoid the so called N+1 queries problem, the tuning is done mostly via configuration and is not explicit in the code. All Squeryl data retrieval revolve around the Queryable[A] trait, which by its lazy evaluation allows statements to be built with the desired granularity, and evaluated in a second step. This approach also has the added benefit that by looking at the code one can make a reasonable guess as to how it will translate into database queries.