Fast Object Queries for Hibernate

Overcome performance and scalability problems of HQL queries without escaping to SQL: Write compact object queries with Hibernate and still get efficient SQL!

New: Commercial version now available for purchase!

What is FastOQL™?

FastOQL™ is a Java library that compiles complex OQL (Object Query Language) queries into highly optimized and efficient SQL queries. It is designed to work with Hibernate, as an alternative to its HQL, to address its performance and scalability problems.

What problem does FastOQL™ solve?

To search for a (large or even a small) set of objects or data that satisfy some complex criteria, spanning over many classes and relationships in a large database, Hibernate developers use HQL or Criteria queries.

However, it is a very common and well-known problem that HQL queries, especially complex ones with many joins across class hierarchies, may perform very poorly, especially if executed on medium or large databases with millions of objects. In such cases, Hibernate developers often escape from HQL to native SQL, giving up the object perspective and compactness of queries.

Complex SQL queries are, however, cumbersome and difficult to construct, understand, and maintain. FastOQL™ solves this problem by producing optimal SQL queries with a minimal number of joins from object queries. Here is a quick illustration.

What benefits does FastOQL™ bring?

By producing and executing optimized SQL queries, FastOQL™ outperforms Hibernate's HQL dramatically. FastOQL™'s queries scale much better than HQL's with the depth of the class hierarchy, with the number of hops over associations (joined classes), as well as with the size of the object space (number of database records). Execution of an SQL query produced by FastOQL™ may be from a few times to a few orders of magnitude faster than of the equivalent one produced by Hibernate. In many cases, queries produced by FastOQL™ can be tractable and will execute in a reasonable time, while the same HQL queries execute forever and fail. See a detailed report from a comparative performance analysis...

How does FastOQL™ do it?

FastOQL™ uses a special dialect of OQL. It is similar in its syntax and semantics with HQL, although there are some minor differences. Learning OQL and switching from HQL to OQL is easy and straightforward. OQL is in some aspects of syntax more concise than HQL, and has some extra features, such as type specialization (downcasting). On the other hand, it does not support all features of HQL. Learn more about features, syntax, and semantics of OQL...

FastOQL™ is a Java library that provides a simple Java API for executing OQL queries provided as strings. OQL queries can be parameterized. FastOQL™ compiles an OQL query into its SQL form according to the object-relational mapping defined in Hibernate. The result is obtained as a simple result set, just as in JDBC. More details...

FastOQL™ is based on the SOLoist technology. It is an adaptation of SOLoist's OQL compiler for Hibernate. SOLoist is an advanced framework for rapid model-driven development of business, Web-based applications with an executable UML, especially suitable for complex systems with large databases.

When can FastOQL™ help?

FastOQL™ is not a wizard that can do impossible and unconditionally improve query performance. There is no any magic behind FastOQL™: it simply produces compact SQL queries that do not have redundancies. This means that an SQL query produced by FastOQL™ will not joint those tables that are not necessary, simply because there is no data in those tables relevant for the query. FastOQL™, of course, preserves the semantics of the source query, and will certainly have to join any table that contains the data that are used in the query. In other words, FastOQL™ will avoid all unnecessary joins that would a straightforward object-to-relational translation of an object query introduce, but cannot remove those that are necessary to preserve the semantics of the query. Therefore, the effect of FastOQL™ depends on the amount of redundancies (often produced by Hibernate) that a straightforward object-to-relational translation of an object query introduces; if there is no such redundancy, FastOQL™ cannot bring any benefit. Nevertheless, in many practical cases of complex queries, there are many joins that can be omitted. This is similar to compressing files: you can sometimes compress a file to 20% of its original size, or you can get only a 5% reduction by compressing a file, all depending on the amount of redundancy in the file. If the file is already compressed, there is no any benefit from compressing it again.

In many cases, however, queries used in practice are such that can be optimized by FastOQL™. Here are the principal circumstances when FastOQL™ is effective:

  • A class participating in the query takes part in an inheritance hierarchy, but the query does not refer to any inherited property of that class.
  • There is a relationship in the query’s navigation clause that is mapped to a separate table (one-to-many or many-to-many), but the query does not refer to any property of a class in that relationship.
  • There is a specialization (downcasting) in the query.

Knowing these rules, you may try to reformulate your problematic query in order to achieve the best performance with FastOQL™ and solve the problem the query may still have with Hibernate HQL. Or you may ask us for help, we will try our best to do this for you!