简体   繁体   中英

Hibernate nested properties criteria

Let's assume, each song belongs to exactly one album created by exactly one artist living in exactly one country. A query like

createCriteria(Song.class)
    .add(Restrictions.eq("album.artist.country.id", 43)); 

fails and can be fixed using createAlias or createCriteria (like here ) so that the needed joins get performed. I'm doing it and it works, but I'm missing some background:

Why does it work like this? Assuming no embedded properties, joining is the only choice, isn't it?

Concerning the join type , there's no ambiguity: It must be an INNER JOIN, otherwise the equality could not hold, right?

The questions about why something is built the way it is are always tricky, and you would probably need to ask authors directly about it.

I was not able to find any official documentation about this, but I assume it has to do with String-based queries (HQL) vs object-based queries (Criteria).

The query you wrote is anyway more HQL than Criteria, so why not use HQL for the entire query?

I understand that this is just a short example you wrote to describe the concept and that it may be convenient to use String-based path navigation joins in more complex Criteria queries also, but the point of Criteria is to provide more type-safe queries and reusable criteria parts which you can use to build the query in chunks, based on various other conditions that that influence what the final query will look like.

For example, say you have predefined constants for all of the entity properties so that you are sure you don't make any typos when working with String-based queries:

public final class Album_ {
  public static final String artist = "artist";
}

public final class Artist_ {
  public static final String country = "country";
}

There are tools/frameworks that generate these classes automatically.

So, you can generate a Criteria the following way:

createCriteria(Song.class)
 .createCriteria(Album_.artist)
 .createCriteria(Artist_.country)
 ...

For most queries the above approach is an unnecessary overhead and make the code less readable IMHO (I personally find HQL/JPQL more readable even when StringBuilder or similar is involved), but I think that's the basic idea behind Criteria: safer and more reusable query parts.

Concerning the join type, there's no ambiguity: It must be an INNER JOIN, otherwise the equality could not hold, right?

You should use INNER JOIN.

Why does it work like this?

Because hibernate generates, so you should put alias.

Have you thought about Hibernate Native SQL instead? Because there would be a messy query to database.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM