Convert HQL query into SQL in Java logs - java

I have a sample query like the following
String hql = "from Stock s where s.stockCode = :stockCode";
List result = session.createQuery(hql)
.setParameter("stockCode", "7277")
.list();
the result is a list like I expect it to be but I want to know how I can sysout the sql query in my Tomcat logs before the query is executed. Can I do it at the code level as opposed to setting a property in log4j or hibernate config?
In this case, I am looking for an output like
select * from Stock s where s.code = 123;

To access SQL at the code level, you can use the datasource proxy library with a listener.
You can find the example of the datasource proxy and its listener at my github repo jpa-puzzles.
However, if you only want to see the sql-s with bound parameters (show-sql shows only sql-s without bound parameters), it's easier to use a hibernate configuration:
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

Related

fetching single column values in JPA

I want to get all the values from a particular column in JPA and store all values into a list. currently, I am using the below approach but I am getting records in something else format.can someone please help me out
Query q1 = factory.createNativeQuery("select * from booking_attendee where booking_id="+id);
List<String> em1=q1.getResultList();
return em1;
query otput
em=[[Ljava.lang.Object;#68606667, [Ljava.lang.Object;#2cd7f99a, [Ljava.lang.Object;#137a5a5, [Ljava.lang.Object;#a45cc1c, [Ljava.lang.Object;#61fdc06d, [Ljava.lang.Object;#72f5eee1, [Ljava.lang.Object;#4e536797]
If you want to create a native query for this, it is more about how to solve this in SQL. You do not say SELECT * which means all columns. You would have to say SELECT your_column_name to select only a specific column.
Query q1 = factory.createNativeQuery("SELECT your_column FROM booking_attendee");
List<String> em1 = q1.getResultList();
The WHERE clause could and should be defined with the parameter binding of JPA. There are several advantages concerning performance and SQL injection.
Named parameter binding is special to the persistence provider (e.g. Hibernate). The common way for JPA is using ? to let your code be portable to other providers.
Query q1 = factory.createNativeQuery("SELECT your_column FROM booking_attendee b WHERE b.booking_id = ?");
q1.setParameter(1, id);
List<String> em1 = q1.getResultList();
Native queries offer the possibilities to use original SQL. Like this, some features which are specific for your database could be used with this. Nevertheless, if you do not have very specific SQL code, you should also have a look in JPQL, the specific query language of JPA, and the JPA Criteria API which offers advantages when you want to refactor your code, shows errors during compile time and makes the dynamic creation of queries easier.

Execute dynamic query with Spring Data JPA

#Query(value = "SELECT * FROM H4 WHERE 1")
List getResult();
Instead of the query "SELECT * FROM H4 WHERE 1" I want to put a String variable containing query generated elsewhere.
#Query, like any other annotation, uses a compile time constant to define attributes. You can't define it's value in runtime unless you plan to hack the Spring Data JPA framework.
You should use either Specifications with criteria, Query by example or JPQL to define and execute your dynamic query.
Create constants and set the value as below.
#Query(value = ApplicationConstantClass.QUERY_STRING_CONSTANT)
List getResult();
or Use EntityManager or SessionFactory of hibernate to execute dynamically generated query.

How to get bound parameters out of a Hibernate Criteria object?

I am running a complex query via the Hibernate Criteria API. During debug, I would like to be able to extract and log the parameters that have been bound to the criteria object. Using Hibernate's org.Hibernate.type logger is not an option because during the server start there are many many queries that are run and the logger causes a serious performance hit, and as we are using Hibernate 3.5, it cannot be configured to be turned on before and after the specific method call, only when the server starts.
As far as getting the SQL query itself, in this answer someone posted excellent code that allows for extracting the SQL from a criteria, is there a similar solution for the bound parameters?
You can log the Criteria and the Restrictions will be displayed as well:
Criteria criteria = session.createCriteria(Post.class)
.add(Restrictions.eq("title", "post"));
LOGGER.info("Criteria: {}", criteria);
will display:
Criteria: CriteriaImpl(com.vladmihalcea.book.hpjp.hibernate.association.AllAssociationTest$Post:this[][title=post])

spring jdbc template returns an empty result

I have the following code
resultList = daoResources.jdbcTemplate.query(sql, selectParams, new BeanPropertyRowMapper(resultClass));
SQL when run with the selectParams against database, I get result. The selecting fields name of the sql matches with the fields in the resultClass too. But for above code, I get an empty resultList.
Where could be the problem?
Debugging is your friend in this scenario. I suggest you enable debug logs for jdbc template to see what sql's and bind parameters are sent to database. Below is from the 3.0.x reference doc
All SQL issued by this class is logged at the DEBUG level under the
category corresponding to the fully qualified class name of the
template instance (typically JdbcTemplate, but it may be different if
you are using a custom subclass of the JdbcTemplate class).

JPA Query toString

I have a JPA Query I am executing on the Google App-Engine datastore.
I am building the query using parameters.
After all parameters have been inputted, I wish to view the Query String.
That is, I wish to view the actual query being executed by the datastore.
Is that even possible?
It would really help me in debugging.
To SOLVE the question, assume the following query:
Query query=EM.createQuery("SELECT FROM "
+MyClass.class.getName()+" C WHERE C.field = :arg1");
query.setParameter("arg1", someParam);
if System.out.println(SomeObj) prints 'SELECT FROM MyClass C WHERE C.field = 17'
then the question is solved.
David
That is, I wish to view the actual query being executed by the datastore.
Enabling DEBUG for the DataNucleus.Datastore log category should do it. Check the DataNucleus Logging documentation.
In current DataNucleus you can just call toString() on the JPA Query object to see the single-string form (without parameter substitution). The actual query invoked on the datastore depends on the datastore (obviously), being SQL in the case of RDBMS, and something else in the case of BigTable.

Categories