Compile time check in Blaze-Persistence?

Hi!

In Blaze Persistence is it possible to have compile-time check ?

CriteriaBuilder<Integer> cb = cbf.create(em, Integer.class)
    .from(Cat.class)
    .select("cat.age");

In this query, if by mistake I write “cat.aged” (age is a property of Cat), there won’t be any compile time exception, right ?

I understand from the documentation that compile time check is possible if using Entity Views module, is it correct?

And without Entity Views, with just the basic setup and packages ?

Thanks in advance!

Some people use the constants that the Hibernate JPA metamodel generator produces for some type-safety i.e.

CriteriaBuilder<Integer> cb = cbf.create(em, Integer.class)
  .from(Cat.class)
  .select(Cat_.AGE);

But that will obviously not check at compile time if the age attribute is assignable to Integer. The checks for entity views are at application boot time, though they are more thorough, i.e. assignability is checked.

You can also write queries with the JPA Criteria API or QueryDSL if you would like to exchange a little readability for type-safety.

1 Like

Thanks a lot! Is the (partial) compile time check with Hibernate JPA metamodel generator also working with implicit or explicit JOIN statements, subqueries etc.? I.e. can a BP query always be rewritten so that there is this kind of check at compile time.

Here is an example with explicit JOIN :

CriteriaBuilder<Integer> cb = cbf.create(em, Integer.class)
    .from(Cat.class)
    .select("kittens.age")
    .where("kitty.age").gt(1)
    .innerJoin("kittens", "kitty");

Since Hibernate ORM and JPA don’t support implicit joins over collections, that’s not going to work unfortunately. You would have to reformulate your query to use explicit joins then.

1 Like

Just to make sure I have understood you correctly, the query :

CriteriaBuilder<Integer> cb = cbf.create(em, Integer.class)
.from(Cat.class)
.select("kittens.age")
.where("kitty.age").gt(1)
.innerJoin("kittens", "kitty");

will not work, as it is written ? I took it from here:

3.1.2 paragraph

This example will work as it is, but you asked about whether this BP query could be rewritten to JPA Criteria to achieve compile time checks:

And the answer is yes, but you would need to use an explicit join in the select clause i.e. instead of kittens.age you will have to refer to kitty.age directly, because JPA Criteria and Hibernate ORM don’t support implicit joins over collections.

For the sake of example, this could be written as:

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Integer> query = cb.createQuery(Integer.class);
Root<Cat> cat = query.from(Cat.class);
SetJoin<Cat, Cat> kitty = cat.join(Cat_.kittens);
query.where(cb.greaterThan(kitty.get(Cat_.age), 1));
query.select(kitty.get(Cat_.age));

Ok, thanks a lot, I have understood now.

Actually, I have not formulated my question well :

the question was : can i rewrite in Blaze-Persistence the query with JOINs (and yes, the query is already written in Blaze Persistence) but with compile time checks, so using the Hibernate JPA metamodel. So rewrite the same query, in Blaze-Persistence, but with compile-time checks (that remain partial, as I understood from your first reply).

And the fact BP supports implicit JOIN over collections is good news.

I guess you could write something like this:

CriteriaBuilder<Integer> cb = cbf.create(em, Integer.class)
    .from(Cat.class)
    .select("kitty." + Cat_.AGE)
    .where("kitty." + Cat_.AGE).gt(1)
    .innerJoin(Cat_.KITTENS, "kitty");

But note that you don’t have to fully give up on type safety. Blaze-Persistence has a QueryDSL frontend as well as a JPA Criteria API frontend as well, which both produce the Blaze-Persistence CriteriaBuilder in the end. So you can still combine that with entity views or write most of your query with one API and switch to the Blaze-Persistence CriteriaBuilder API when needed.