Search code examples
javahql

HQL - Select nested objects


Consider the following scenario: two database tables (producers and produce), with a one to many relation (one produce is created by one producer, one producer has many products), each table with multiple fields (including name and id).

Also, consider I have two managed entities (Producer and Produce) and two smaller versions of the these objects (unmanaged) used as DTOs (ProducerDTO and ProduceDTO) with only name and ID (and the relation).

I want to select using an HQL query a specific product (as a DTO) with it's producer set as well. More clearly: SELECT new ProduceDTO(produce.id, new ProducerDTO(producer.id, producer.name), produce.name) FROM Produce produce JOIN produce.producer producer WHERE ...

But I get a QuerySyntaxException: unexpected token: , after produce.id in the query. So my question would be: is it possible to select nested custom objects in HQL and if so, what are the rules / limitations for this? For a single custom object, it works just fine, but when I try to nest 2 or more, I'm having issues.

Note: the question is to better understand the phenomenon, not necessarily for this specific case (I already have a workaround for my case with my actual classes).

Thanks!


Solution

  • The full JPA query language syntax specification can be found in official Java EE 7 documentation here: http://docs.oracle.com/javaee/7/tutorial/persistence-querylanguage005.htm#BNBUF

    Specifically, the parts that answer your question are:

    constructor_expression ::= NEW constructor_name(constructor_item {, constructor_item}*)
    
    constructor_item ::= single_valued_path_expression
                       | aggregate_expression
    

    So this basically means

    1. You can't use a null constructor.
    2. Each parameter can be either single_valued_path_expression or aggregate_expression.

    Further, constructor_expression is present only in select_expression that can be used only as a top-level query construct, so per standard JPQL you can't do tricks with nested select ... statements. I couldn't find a complete specification of HQL online, so not sure about that one.