Before we start discussing how to build expressions, it is important to understand one group of expressions widely used in Cayenne: path expressions. There are two types of path expressions: object path used to navigate graphs of Java objects that follow Java Bean property naming conventions and database path used to navigate the database schema. General form of path expressions is the following:
[db:]segment[+][.segment[+]...]
An Object Path Expression is a property navigation path. Such path is represented by a String made of dot-separated names of properties of a Java Bean class. E.g. a path expression "toArtist.artistName" is a valid property path for a Painting class, pointing to the name of the Artist who created a given Painting. A few more examples:
![]() | What Does 'navigation' Means The term "navigation" in the description above could mean different things depending on the context. For instance, when evaluating an expression in memory, "navigating" an object path would simply return the value of a corresponding object property. When the same expression is used in a select query qualifier, it resolves to the name of a table column used in a WHERE clause of a generated SQL statement. |
Database Path Expressions provide an easy way to navigate through DB table joins. Instead of complex join semantics such expressions utilize the names of DbRelationships defined in Cayenne DataMap. Translating the above object path examples into the DB realm, database path expressions might look like this:
Though database path expressions are widely used by Cayenne framework internally, they are rarely used in applications. Although there are a few cases when their explicit use is justified.
When Cayenne is performing a database query which uses more than one path expression with common elements, those expressions will be merged automatically. This improves database query speed and simplifies the SQL, but when your path expression is one-to-many it may not give you what you expect.
Expression e1 = ExpressionFactory.like("toArtist.exhibitArray.title", "foo"); Expression e2 = ExpressionFactory.like("toArtist.exhibitArray.title", "bar"); Expression e = e1.andExp(e2); q = new SelectQuery(Painting.class, e);
This will always give you no results because the query will look for exhibits which are titled 'foo' AND 'bar'. Of course there is no exhibit which has both names.
Cayenne supports "aliases" in path Expressions to solve this.
Expression e1 = ExpressionFactory.like("exhibitAlias1.title", "foo"); Expression e2 = ExpressionFactory.like("exhibitAlias2.title", "bar"); Expression e = e1.andExp(e2); q = new SelectQuery(Painting.class, e); q.aliasPathSplits("toArtist.exhibitArray.title", "exhibitAlias1", "exhibitAlias2");
That last command tells the select query how to interpret the alias. Because the aliases are different, the SQL generated will have two completely separate set of joins. In other words you will "find all paintings by any artist who has at least one exhibition titled 'foo' and at least one exhibition titled 'bar'". This is called a "split path".
On their own path expressions are just strings. You'll want to create an Expression to do something useful.