Ebean Query Language (EQL)
Overview
Ebean Query Language (EQL) was a SQL-like query language available in Ebean 16.x releases that allowed you to write queries using a string-based syntax similar to SQL. EQL queries were parsed early and converted to type-safe Query objects that could be further modified before execution.
EQL has been removed in Ebean 17.x in favor of more type-safe approaches using Query Beans (recommended) and the standard Query API.
EQL Syntax (16.x reference)
This section documents EQL syntax for reference if you are maintaining an Ebean 16.x application.
Basic Structure
EQL queries followed this basic pattern:
find [selected-properties]
[fetch property-paths]
where [predicates]
order by [order-by-clause]
limit [limit-clause]
Complete Example (16.x)
String eql = " where customer.name like :custName " +
" and orderDate > :minOrderDate " +
" order by id desc " +
" limit 50 ";
List<Order> orders = DB.createQuery(Order.class, eql)
.setParameter("custName", "Rob%")
.setParameter("minOrderDate", lastWeek)
.findList();
WHERE Clause
The where clause contained predicates using property paths:
"where customer.name like :custName" // string comparison
"where status = :status" // property equals
"where orderDate > :date" // date comparison
"where amount between :min and :max" // range check
"where customer.id in :customerIds" // IN clause
"where items.size > 0" // collection check
ORDER BY Clause
"order by id" // ascending
"order by id desc" // descending
"order by customer.id, id desc" // multiple properties
SELECT and FETCH
// Select specific properties from root entity
"select (name, email) where status = :status"
// Fetch properties from related entities
"fetch customer (id, name) where status = :status"
"fetch customer.address (city, country) fetch items where ..."
// Named query definition
@NamedQuery(
name="bugStatus",
query="fetch loggedBugs where loggedBugs.status = :bugStatus order by name"
)
Why EQL Was Removed
- Lack of type safety: Query strings are error-prone and can only be validated at runtime
- No IDE support: String-based syntax does not benefit from IDE auto-completion or refactoring
- Maintenance burden: Maintaining a custom query parser was resource-intensive
- Better alternatives: Query Beans provide the same functionality with compile-time safety
- Industry trend: Modern ORMs favor type-safe query builders
Migrating from EQL to 17.x
See Upgrading from 16.x to 17.x for detailed migration examples converting EQL queries to:
- Query Beans (Recommended) - Type-safe, compile-time checking, IDE auto-completion
- Standard Query API - Fluent API using method calls
- Raw SQL / SqlQuery - For complex database-specific queries
Quick Migration Example
EQL (16.x):
String eql = "where customer.name like :custName and orderDate > :minOrderDate " +
"order by id desc limit 50";
List<Order> orders = DB.createQuery(Order.class, eql)
.setParameter("custName", "Rob%")
.setParameter("minOrderDate", lastWeek)
.findList();
Query Beans (17.x - Recommended):
List<Order> orders = new QOrder()
.customer.name.contains("Rob")
.orderDate.greaterThan(lastWeek)
.orderBy().id.desc()
.setMaxRows(50)
.findList();
Standard Query API (17.x - Alternative):
List<Order> orders = DB.find(Order.class)
.where()
.contains("customer.name", "Rob")
.gt("orderDate", lastWeek)
.order().desc("id")
.setMaxRows(50)
.findList();
Named Queries (16.x)
Named Queries in Ebean 16.x used EQL syntax defined in @NamedQuery annotations.
In Ebean 17.x, Named Queries still exist but the EQL syntax within them is no longer actively used.
16.x Named Query Definition:
@NamedQueries(value={
@NamedQuery(
name="bugsSummary",
query="find (name, email) fetch loggedBugs (title, status) where id=:id "),
@NamedQuery(
name="bugStatus",
query="fetch loggedBugs where loggedBugs.status = :bugStatus order by name")
})
@Entity
public class User {
...
}
16.x Named Query Execution:
User user = DB.createNamedQuery(User.class, "bugsSummary")
.setParameter("id", 1)
.findOne();
17.x Alternative: Use Query Beans or standard Query API directly instead of Named Queries.
Resources
- Query Beans Documentation - Type-safe query alternative
- Where Clause Documentation - Standard Query API for predicates
- Upgrading from 16.x to 17.x - Detailed migration guide
- Query Documentation Index - All query methods and options
Troubleshooting
Q: I see "DB.createQuery() no longer accepts an EQL query string" error
A: You are using Ebean 17.x which removed EQL support. The method DB.createQuery(Class, eqlString)
no longer exists. Use one of these alternatives:
- Query Beans (recommended):
new QCustomer().name.eq("Rob").findOne() - Standard Query API:
DB.find(Customer.class).where().eq("name", "Rob").findOne() - Raw SQL:
DB.findNative(Customer.class, sqlString)
Q: Can I still use Ebean 16.x with EQL?
A: Yes, Ebean 16.x continues to receive maintenance updates. See releases for available 16.x versions.
Q: Where can I find more migration help?
A: See the Upgrading from 16.x to 17.x guide for detailed examples and migration strategies.