简体   繁体   中英

Hibernate - How to execute named native query without mapping to a specific class

I have a very complicated query that doesn't convert to HQL, so I must use SQL. I put my query into a NamedNativeQuery annotation. It "should" return a list of two values ( List<Object[2]> ). When I try to run, the session fails to load the query because I haven't defined a mapping or result class. I cannot create a simple class to map these values to because the annotations have to go in a specific DAO project and the code that is using the queries exists in its own project. (The DAO project is more general-purpose and the entities in that project map directly to tables in our database. I cannot just create a small class in this project to map to my query result because it wouldn't fit the schema of this project)

Is there a way for me to map the query results to a more generic class, or even better is there some way for me to just get a List<Object[]> back without having to map at all to anything particular? This is extremely frustrating that Hibernate has to work in this particular way when all I want to do is execute a query and get the result back as an array.

This is the code that I use for storing the result of a SQL query in a List<Object[]> . Maybe you can adapt it to what you need:

    public List<Object[]> executeSelectQuery(String sqlQuery) {

       List<Object[]> cleanedResults = new ArrayList<Object[]>();

       SQLQuery query = sessionFactory.getCurrentSession().createSQLQuery(sqlQuery);
       List<Object[]> hibernateResults = query.list();

       // Hibernate does not return always a List<Object[]>, but a list of strings or integers, so it is necessary to check the returned values

       if (!hibernateResults.isEmpty()) {
           if (hibernateResults.get(0) instanceof Object[]) {
               cleanedResults = hibernateResults;
           } else {
               Object[] row;
               // Use a 'for' because 'foreach' sometimes has casting exceptions converting to object
               for (int i = 0; i < hibernateResults.size(); i++) {
                  row = new Object[1];
                  row[0] = hibernateResults.get(i);
                  cleanedResults.add(row);
               }
           }
        }

        return cleanedResults;
    }

A NamedNativeQuery supports an addition annotation to allow you map the result to a POJO:

@SqlResultSetMapping(name="MyResult.Mapping", entities = {
    @EntityResult(entityClass=MyResult.class, fields = {
        @FieldResult(name="email", column="email"),
        @FieldResult(name="name", column="name")
    })
})

Then add resultSetMapping="MyResult.Mapping" to your NamedNativeQuery annotation.

I ended up not using NamedNativeQueries because they weren't working for me. Instead, I just used session.createSQLQuery with constant Strings, and it worked.

I probably didn't phrase my question properly. I could not use a @SqlResultSetMapping because I didn't have any classes to map to based on the structure of the code I am working with. My query has to come out as a List<Object[]> result, and there is no way to do that with NamedNativeQueries because Hibernate doesn't support it.

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