Get dynamic SQL column names from Hibernate - java

I have an Oracle table that has a CLOB in it. Inside this CLOB can be a SQL statement. This can be changed at any time.
I am currently trying to dynamically run these SQL statements and return the column names and data back. This is to be used to dynamically create a table on the web page.
Using Hibernate, I create the query and get the data like so:
List<Object[]> queryResults = null;
SQLQuery q = session.createSQLQuery(sqlText);
queryResults = q.list();
This gets the data I need, but not the column names. I have tried using the getReturnAliases() method, but it throws an error that the "java.lang.UnsupportedOperationException: SQL queries do not currently support returning aliases"
So my question is: Is there a way through Hibernate to get these values dynamically?

You can use :
q.setResultTransformer(AliasToEntityMapResultTransformer.INSTANCE);
List<Map<String,Object>> aliasToValueMapList=query.list();
to get column names in createSQLQuery.
For more details please refer to this question.

You can use the addScalar method to define the columns.
Look at 16.1.1
https://docs.jboss.org/hibernate/orm/3.3/reference/en-US/html/querysql.html

You could implement a ResultTransformer ( http://docs.jboss.org/hibernate/orm/4.3/javadocs/org/hibernate/transform/ResultTransformer.html ) and set it on the native query. I think with a native SQL query you get the aliases as specified in the SQL as alias parameter in the callback method.

In 2018 I would suggest using NativeQueryTupleTransformer with native queries.
query.setResultTransformer(new NativeQueryTupleTransformer());
The result format is List<Tuple>. This format is very convenient to work with native SQL queries.

Related

Get native SQL string from JPAQuery

I'm using Spring Data JPA + QueryDSL. I create my dynamic queries like this:
JPAQuery<Foo> query = jpaQueryFactory.select(...);
I have found this old article that shows how to retrieve programatically the native sql string: https://antoniogoncalves.org/2012/05/24/how-to-get-the-jpqlsql-string-from-a-criteriaquery-in-jpa/ but it doesn't work for me.
I have tried this:
String queryString1 = query.createQuery().unwrap(org.hibernate.query.Query.class).getQueryString();
String queryString2 = query.createQuery().unwrap(org.eclipse.persistence.jpa.JpaQuery.class).getDatabaseQuery().getSQLString();
The first doesn't returns me the the native sql but the JPQL string and the second fails to unrwap org.hibernate.query.internal.QueryImpl to org.eclipse.persistence.jpa.JpaQuery.
PS: I've tested before and after fetching the query.
If you need native SQL query generated by Querydsl, then you need to use SQLQueryFactory instead JPAQueryFactory. Your JPQL query returned by JPAQueryFactory is transformed to SQL by JPA not by Querydsl.

JOOQ How to do UNION and WHERE IN

I'm using org.jooq.impl.Executor to create a query that I want to pass to JdbcOperations. I'm passing parameter values by using .where(Condition...).
After chaining methods for the executor, I get a Query object. The problem is when I call query.getSQL(), the returned query string contains parameters ?,?,? instead of my inserted values.
This is the code I'm using to build the SQL query.
Note that TableA has three foreign keys to TableB. I tried to use JOIN ON with OR to join TableA and TableB but the performance was too slow.
Query query = executor.select(fieldsToSelect)
.from("TableA")
.join("TableB").on("TableA.FirstForeignKey = TableB.TableBID")
.join("TableC")
.on("TableC.TableCID = TableB.TableCForeignKey")
.where(condition)
.union(executor.select(fieldsToSelect)
.from("TableA")
.join("TableB").on("TableA.SecondForeignKey = TableB.TableBID")
.join("TableC")
.on("TableC.TableCID = TableB.TableCForeignKey")
.where(condition)
.union(executor.select(fieldsToSelect)
.from("TableA")
.join("TableB").on("TableA.ThirdForeignKey = TableB.TableBID")
.join("TableC")
.on("TableC.TableCID = TableB.TableCForeignKey")
.where(condition)));
This is how I create Condition object for the executor:
MySQLFactory.fieldByName(Integer.class, TABLE_NAME_TABLEA, "TableAID")
.in(ArrayUtils.toObject(ids));
This is how I perform the query:
jdbcOperations.query(query.getSQL(),query.getBindValues().toArray(), myMapper);
How can I correctly map parameters with values and use the query with JdbcOperations?
By default, the Query.getSQL() method returns a query with bind variables (?). You'll then pass that SQL string to a PreparedStatement and bind the variables individually, extracting them first via Query.getBindValue()
An alternative version of the Query.getSQL(boolean) or Query.getSQL(ParamType) method will indicate to jOOQ that the bind variables should be inlined into the SQL string, in order to form a static SQL statement, not a prepared statement.
You can also tell jOOQ to generate all SQL statements as static statements by using StatementType.STATIC_STATEMENT on the Settings that you provide the jOOQ Configuration with.
This is all documented here:
http://www.jooq.org/doc/latest/manual/sql-building/bind-values/inlined-parameters/

How to use CONCAT_WS() in Hibernate HQL

To combine multiple columns as one,
I found one answer
SELECT id,CONCAT_WS(',', field_1, field_2, field_3, field_4) list
FROM `table`;
This query working fine in SQL but it gives me error in HQL:
Error is .
(java.lang.IllegalStateException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode )
please help me to find out what wrong i did, help me to know how to use CONCAT_WS() IN HQL
below how i written my HQL query
SELECT C1._URI,C1.HEALTH_FACILITY,C1.DISTRICT,CONCAT_WS(',', C1.BLOCKS_OF_BHUBRI, C1.BLOCKS_OF_GOLAGHAT, C1.BLOCKS_OF_HAILAKANDI) as Block_name
FROM GapAnalysisWashInHealthFacilitiesCore C1
any help will appreciate
CONCAT_WS is a function specific to mySql. HQL is a generic language and not aware of native SQL functions and syntax. If you really need the function, then you should use Hibernate's API for native SQL.
Session session = ...;
Query query = session.createSQLQuery("
SELECT id,CONCAT_WS(',', field_1, field_2, field_3, field_4) Block_name FROM `table`");
List result = query.list();
Then you may like to have a look at Result Transformers to get result as list of GapAnalysisWashInHealthFacilitiesCore objects.

Converting HQL to SQL query

I wanted to know how can we convert a HQL query into a sql query .I know if we make the showsql = true parameter on we can get the sql query but the parameter value would not be appended with its values .I need to find ways to print the SQL query generated in logs and use for my performance optimization .
Thanks in advance
You can check my answer here: https://stackoverflow.com/a/37749916/1350643
In short you can use following code to convert hql to sql:
QueryTranslatorFactory translatorFactory = new ASTQueryTranslatorFactory();
SessionFactoryImplementor factory = (SessionFactoryImplementor) getSessionFactory();
QueryTranslator translator = translatorFactory.
createQueryTranslator(hqlQueryText, hqlQueryText, Collections.EMPTY_MAP, factory);
translator.compile(Collections.EMPTY_MAP, false);
translator.getSQLString();
Source: http://narcanti.keyboardsamurais.de/hibernate-hql-to-sql-translation.html
Hibernate uses dialects for specific optimizations. Maybe you could extend one of the existing Oracle dialects or supply your own.You can create your custom dialect by subclassing the Oracle dialect.

Hibernate session.createQuery error while replace method with single quote

I got very typical issue. My dynamically generated query like this...
UPDATE Templates t SET t.TEMPLATE_DATA = replace(t.TEMPLATE_DATA, 'Test\'s Test', 'Kent"s Test'), t.TEMPLATE_DATA = replace(t.TEMPLATE_DATA, 'Test&quot;s&#32;Test', 'Kent"s Test'), UPDATE_DATE = NOW() where PRACTICE_ID = 1 AND CATEGORY_ID IN (1)
This works perfect when I explictily fire this query in db. but by using hibernate's session.createQuery(-- my query --) if thwows an error QueryTranslatorException.
Database : Mysql 5.3
Have any one faced this issue?
Thanks in advance.
Try to run this in Hibernate as native SQL query:
session.createSQLQuery(-- query text --);
Because if you use
session.createQuery(-- query text --);
Hibernate will try to execute it as HQL query which differs from usual SQL query.
HQL is object oriented query language. It operates in terms of objects rather then in terms of tables. Here posted a brief description of difference between SQL and HQL. But if you have time better to read appropriate sections of hibernate's documentation about HQL and Native SQL usage.
If you want to execute SQL Query in hibernate, Use : session.createSQLQuery(String query);

Categories