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.