Returning multiple object types using hibernate using an inner join

前端 未结 3 1503
被撕碎了的回忆
被撕碎了的回忆 2020-12-30 01:55

I seem to be having some difficulty with a query in hibernate. I am performing an inner join on two tables.

SELECT * FROM product p INNER JOIN warehouse w ON         


        
相关标签:
3条回答
  • 2020-12-30 02:22

    As coding_idiot said, maybe you don't know the entity for your query result because they are from different classes, you can access to every object in the element.

    1. Create a List<Object> to retrieve the query result (Example: List<Object> objs = (List<Object>)query.getResultList();)
    2. Iterate through this array using a for (Example: for (Object obj : objs){...})
    3. Every element of List<Object> has got a Object[] so cast every element to this class (Example: Object[] o = (Object[]) obj; )
    4. Access to the element through its index number (Example: o[4])

    Code sample:

        Query query = JPA.em().createNativeQuery("SELECT * FROM product p
        INNER JOIN warehouse w ON p.wid = w.id");
    
        /* I suppose that it return fields sorted by entities and field in
        database:
        *
        * 0: product.id | 1: product.name | 2: product.wid | 3: product.price | 4: product.stock | n-1: product.N-1Field
        * n: warehouse.id | n+1: name | n+2: warehouse.city | n+3: warehouse.lat | n+4: warehouse.long | m-1: warehouse.M-1Field
        *
        * Join result: id | name | wid | price | stock | ... | id | name | city | lat | long | ...
        */
    
        List<Object> objs = (List<Object>)query.getResultList();
    
        for (Object obj : objs) {
            Object[] o = (Object[]) obj;
            String productId =  String.valueOf(o[0]);
            String productName =  String.valueOf(o[1]);
            String productWid =  String.valueOf(o[2]);
    
            ... }
    
    0 讨论(0)
  • 2020-12-30 02:27

    Use the {} form to avoid problems with column name duplication:

    SELECT {p.*}, {w.*} FROM product p INNER JOIN warehouse w ON p.wid = w.id
    

    From Hibernate Reference Documentation, section 18.1.4. Returning multiple entities:

    Until now, the result set column names are assumed to be the same as the column names specified in the mapping document. This can be problematic for SQL queries that join multiple tables, since the same column names can appear in more than one table.

    Column alias injection is needed in the following query (which most likely will fail):

    sess.createSQLQuery("SELECT c.*, m.*  FROM CATS c, CATS m WHERE c.MOTHER_ID = c.ID")
     .addEntity("cat", Cat.class)
     .addEntity("mother", Cat.class)
    

    The query was intended to return two Cat instances per row: a cat and its mother. The query will, however, fail because there is a conflict of names; the instances are mapped to the same column names. Also, on some databases the returned column aliases will most likely be on the form "c.ID", "c.NAME", etc. which are not equal to the columns specified in the mappings ("ID" and "NAME").

    The following form is not vulnerable to column name duplication:

    sess.createSQLQuery("SELECT {cat.*}, {mother.*}  FROM CATS c, CATS m WHERE c.MOTHER_ID = c.ID")
     .addEntity("cat", Cat.class)
     .addEntity("mother", Cat.class)
    

    This query specified:

    the SQL query string, with placeholders for Hibernate to inject column aliases the entities returned by the query The {cat.*} and {mother.*} notation used above is a shorthand for "all properties".

    0 讨论(0)
  • 2020-12-30 02:29

    Reference

    In case the entities aren't from the same class, then here's a sample :

    public static void main(String[] args) {
            Session sess = NewHibernateUtil.getSessionFactory().openSession();
            SQLQuery q = null;
            String query = "select a.*, u.* from user u, account a where a.iduser=u.iduser";
            q = sess.createSQLQuery(query);
            q.addEntity(User.class);
            q.addEntity(Account.class);
            List lst = q.list();
            System.out.println("" + lst.size());
    
            for (int i = 0; i < lst.size(); i++) {
                System.out.println(((Object[]) lst.get(i))[0]);     //account bean, actually this is in reverse order - so this is user bean
                System.out.println(((Object[]) lst.get(i))[1]);     //user bean         & this account bean
            }
            sess.close();
        }
    
    0 讨论(0)
提交回复
热议问题