SELECT NEW in jpql not working

Hi all,
I have a question about the creation of objects in jpql SELECT using the NEW operator.
When I use this query for example:
select new com.company.example.Order(Customer customer) from...

Then I get a Jpql Syntax Error because of an unexpected “(”. I can see that the query is modified before execution, running through parsers and enhancers, adding conditions from row level constraints etc. and the modified query has no longer a space between “new” and “com…”.
select newcom.company.example.Order(Customer customer) from...

So I guess the jpql is indeed broken, is this a known bug and is there a workaround?

Thank you very much in advance!

Hi Oliver,

Are you executing this query through EntityManager?

Regards,
Konstantin

Hi Konstantin,

Thanks for the reply!
No, I am using the DataManager, does this only work with the EntityManager? I will add the original code below, although it contains German words in the query.
If I remember correctly, I debugged into it and at some point the query was enhanced with somthing like “addWhereClause” because we have a row level constraint and in doing so, the query got analzed by a JPA parser into a tree, the NEW expression was reognized and handled and after that, the modified query was returned from a transformer and there the error was present.
If needed, I can take some notes of the classes involved but I have to change some code again for that.
As a workaround, I am using “loadValues” now and create my object from that, that might be a tiny bit more overhead than using NEW directly but it works.

Thanks in advance for any hints!


List<MnkpKontrolle> kontrollen = dataManager.load(MnkpKontrolle.class)
                .query("SELECT NEW de.balvi.ipi.lm.statistik.mnkp.domain.MnkpKontrolle(mnkpBetrieb.statistik, mnkpBetrieb, kontrolle)" +
                       "        from lm_Kontrolle kontrolle" +
                       " join lm_MnkpBetrieb mnkpBetrieb on mnkpBetrieb.betriebsstaette = kontrolle.betriebsstaette" +
                       " where mnkpBetrieb.statistik = :statistik" +
                       "   and kontrolle.kontrolldatum >= :von and kontrolle.kontrolldatum <= :bis" +
                       "   and (kontrolle.kontrollart = 'PLANKONTROLLE'"+
                       " or mnkpBetrieb.katAvvBetriebsart member of kontrolle.katKontrollierteBetriebsarten)"
                )
                .parameter("statistik", kopfdaten)
                .parameter("von", kopfdaten.getZeitraumVon())
                .parameter("bis", kopfdaten.getZeitraumBis())
                .list();

Yes, JPQL constructor expressions now work only in EntityManager. So your workaround with loading first a KeyValueEntity is probably the only way to achieve this with DataManager.

Actually, there is such a request in our issue tracker: Ability to map scalar and aggregate results of JPQL query to POJO · Issue #1246 · jmix-framework/jmix, but it’s not in our plans yet. If you think it’s important, please add a comment to this issue with some motivation.

BTW in your current case, is MnkpKontrolle a JPA or DTO entity?

Thank you, I will do that!

MnkpKontrolle is somehow both a JPA and DTO. It is meant for calculating statistics so we need the underlying entity in another form (DTO) but we also need to save it (JPA) so users might take a look at it later to check if the underlying data of the statistics is correct. So in practice, yes,it is a JPA JMix Entity.