1

This HQL query give me error:

String q4 = "SELECT i, COUNT(ie) FROM CorsoStudi cs \n"
            + "\t JOIN cs.inserogati ie JOIN ie.insegn i \n"      
            + "\t WHERE cs.nome = 'Laurea in Informatica' \n"
            + "\t GROUP BY i"; 

The error is:

Exception in thread "main" java.lang.IllegalArgumentException: org.hibernate.QueryException: could not resolve property: insegn. of: component[_id,annierogazione,annoaccademico,crediti,discriminante,discriminantemodulo,hamoduli,id_facolta,insegn,inserogato_padre,modulo,nomemodulo,nomeunita,programma] 

This is InsErogato:

@Embeddable 
public class InsErogato { 

    private Integer _id; 

    private String annoaccademico; 

    @Embedded 
    private Insegn insegn; 

    @Embedded
    private Discriminante discriminante; 

    private Integer modulo;  

    private String discriminantemodulo; 

    private String nomemodulo; 

    private Double crediti; 

    private String programma; 

    private Integer id_facolta; 

    private String hamoduli;  

    @Embedded 
    private InsErogatoPadre inserogato_padre; 

    private String nomeunita; 

    private Integer annierogazione; 

    // constructors, getters and setters and toString  
}  

and this is Insegn:

@Embeddable
public class Insegn { 

    private Integer _id; 

    private String nomeins;  

    private String codiceins; 

    // constructors, getters and setters and toString 
}  

Main:

// begin transaction 
entityManager.getTransaction().begin();  

List<Object[]> insegn = entityManager
        .createQuery(q4, Object[].class) 
        .getResultList(); 

for(Object[] i : insegn) {
    Insegn ins = (Insegn)i[0]; 
    Long count = (Long)i[1]; 

    System.out.println("nomeins: " + ins.getNomeins() + ", numero inserogati: " + count); 
}  

// commit transaction
entityManager.getTransaction().commit();  

The MongoDB structure:

https://i.stack.imgur.com/qFusC.jpg  
https://i.stack.imgur.com/k04HK.png
https://i.stack.imgur.com/H8nhS.png
https://i.stack.imgur.com/eYl2M.png 

I tried to change the query but Hibernate doesn't find "insegn" (and also "discriminante") property in "inserogato", but he can find other simple attributes from it (like "annoaccademico" etc.).

The same query works on Hibernate ORM with PostgreSQL.

Maybe I have to add something in the annotations, or change the mongoDB structure (?).

I'm using Hibernate OGM 5.3.1.Final and MongoDB 3.6.3 JDBC Driver.

2 Answers2

0

The same query works on Hibernate ORM with PostgreSQL

But PostgreSQL is a SQL database, MongoDB is a NoSQL database. Hibernate OGM is a means to add Hibernate ORM to NoSQL databases. The '(H)SQL' for OGM is limited (see below).

You don't say what your application is deployed on. I use WildFly 12.0.0.Final. I've had OGM with MongoDB working on version 11 & 12.

entityManager.getTransaction().begin();

I use the (WildFly) container to handle transactions. Annotate my EJB.

@TransactionManagement(TransactionManagementType.CONTAINER)

I don't believe you can use (H)SQL per se with Hiberate OGM but:

Use JPQL - only for simple queries for now

Use the NoSQL native query mapping the result as managed entities

Use Hibernate Search queries - primarily full-text queries

It says in the documentation:

In particular and of notice, what is not supported is:

cross entity joins

JPQL functions in particular aggregation functions like count

JPQL update and delete queries

One of my queries:

Query query = mongoDBEntityManager.createQuery("FROM FoodsCosmeticsMedicines f WHERE f.ean = :ean")
                .setParameter("ean", ean);

The entity (the @Expose are for the JSON)

@Entity(name = "FoodsCosmeticsMedicines")
@Indexed
@Table(name = "foodsCosmeticsMedicines")
public class FoodsCosmeticsMedicines implements Serializable {

    // Arrays of Objects
    @Expose(deserialize = true, serialize = true)
    @Embedded
    ProductCharacteristics productCharacteristics;
    @Expose(deserialize = true, serialize = true)
    @Embedded
    CalcNutrition calcNutrition;
    @Expose(deserialize = true, serialize = true)
    @Embedded
    Nutrients nutrients;
    @Expose(deserialize = true, serialize = true)
    @Embedded
    Enumbers enumbers;
    @Expose(deserialize = true, serialize = true)
    @Embedded
    ChemicalsMineralsVitamins chemicalsMineralsVitamins;
    @Expose(deserialize = true, serialize = true)
    @Embedded
    Lifestyle lifestyle;
    .....
}

Why are you using JOIN?

With MySQL I use Hibernate as my ORM I would use annotations to map relationships with entities such as:

@OneToOne(cascade = CascadeType.ALL, mappedBy = "product", fetch = FetchType.LAZY)
private UriEntity uri;

entityManager.getTransaction().commit();

This is irrelevant as all you've done is read. Maybe you excluded the persist?

I'm sure you've read the documentation. I found all the answers to the problems I encountered here:

Hibernate OGM 5.3.1.Final: Reference Guide

NOTiFY
  • 1,255
  • 1
  • 20
  • 36
0

Currently, queries with group by are not supported. You will need to run a native MongoDB query for this particular use case. See the reference documentation for more details about it.

I think the join on an embedded entity instead of a collection is confusing the parser even if it's a valid query. You should see a clearer exception with the following one (equivalent to the one you are trying):

SELECT ie.i, COUNT(ie)
FROM CorsoStudi cs
    JOIN cs.inserogati ie
WHERE cs.nome = 'Laurea in Informatica'
GROUP BY ie.i;

It should throw:

java.lang.UnsupportedOperationException: The GROUP BY clause is not supported

Aggregate functions are not supported as well.

Davide D'Alto
  • 7,421
  • 2
  • 16
  • 30
  • Hi! Thanks for your answer. I noticed that "GROUP BY" is not supported in Hibernate OGM, but I've already tried the query you wrote and it doesn't work anyway because he can't find "insegn" property which is embedded in "inserogato" (and "inserogato" is an element collection of "corsostudi"). Maybe I just can't reach a nested embeddable object (?). – Emanuele Crema May 02 '18 at 13:55
  • Unless you have found a new bug, Queries on embedded collections should work. We have several tests for this use case: https://github.com/hibernate/hibernate-ogm/blob/master/core/src/test/java/org/hibernate/ogm/backendtck/queries/QueriesWithEmbeddedCollectionTest.java Or, maybe you can create a test case so that we can run it and double check. Could also show us `CorsoStudi`. Cheers – Davide D'Alto May 03 '18 at 10:55
  • I know that queries on embedded collections works, I've tried them, but in this case they don't. Maybe because "inserogato" (which embedds "insegn") is an ElementCollection of "CorsoStudi". But I don't know if this is the problem. Btw this is the class "CorsoStudi": https://github.com/emanuelecrema/hibernateOGMExample/blob/master/src/main/java/com/did2014small/collections/CorsoStudi.java I deleted some of the unecessary parts in the code – Emanuele Crema May 03 '18 at 15:42
  • Ok, I think I found out the problem! Query like this are working: `SELECT cs FROM CorsoStudi cs JOIN cs.inserogato ie WHERE ie.insegn.nomeins = 'Logica';` but if I do like this, it doesn't work (because it can't find property insegn): `SELECT ie.insegn FROM CorsoStudi cs JOIN cs.inserogato ie WHERE ie.insegn.nomeins = 'Logica';` So I think the problem is that in Hibernate OGM I can't retreive an embedded object with SELECT (while in Hibernate ORM it's possible). Is it right? – Emanuele Crema May 04 '18 at 09:47
  • I would expect this to work with MongoDB because we have a similar test already in place. Maybe you can spot if there is something different in your code? This is the test: https://github.com/hibernate/hibernate-ogm/blob/master/core/src/test/java/org/hibernate/ogm/backendtck/queries/QueriesWithEmbeddedCollectionTest.java#L170 and this is the entity involved: https://github.com/hibernate/hibernate-ogm/blob/master/core/src/test/java/org/hibernate/ogm/backendtck/queries/StoryGame.java Let me know if you spot any differences. Thanks – Davide D'Alto May 08 '18 at 12:31
  • I checked the Test Case you showed and it's like my case, but in the `SELECT`, it retreives a simple attribure (`score` which is an `Integer` type). So I tried this query and it works: `SELECT ie.insegn.nomeins FROM CorsoStudi cs JOIN cs.inserogato ie WHERE ie.insegn.nomeins = 'Logica';`. So my conclusion is that I can retreive every single attribute from an Embedded Object, but not the Object itself! BTW the mapping of the class is equal to the one you posted. – Emanuele Crema May 09 '18 at 20:29