JPA Query toString - java

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.

Related

Convert HQL query into SQL in Java logs

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

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.

Cannot get update query to work with Hibernate

I have a simple update query just to check if update query works:
this.openDBTransaction();
Query updateQuery = session.createQuery(
"UPDATE User AS usr SET usr.failedLogins=666 WHERE usr.id='USER_3000'"
);
int result = updateQuery.executeUpdate();
this.closeDBTransaction();
but somehow DB is not update with desired value. result came as 1 so something took place but for sure not update query.
Any clue what is going on?
You should use #Transactional annotation so that the compiler knows that the transaction is manipulating the database, thus permits to perform Data Manipulation queries or it will simply execute it as a Data Definition Language query.
Look at the code snippet below, for example,
#Transactional
public Employee editEmployee(Employee employee) { //employee is the data you got through post
return entityManager.merge(e1);
}
Also, the best practice is to always implement Data Access Object Interface and its implementation and define your queries in the implementation.
I hope this helps.

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])

How to use 'Insert' in a nativeSQL query in Hibernate outside the mapped class ?

In Hibernate, you can use the 'SELECT' queries in native SQL like this :
Query query = session.createSQLQuery("SELECT ... FROM ...");
But I would want to use an 'INSERT' query.
So, I looked at the documentation, and it seems you must go directly to the mapped class and write the code inside it.
But I would want to use it as I do for a 'SELECT' query (outside the mapped class) since it looks much more pratical.
Indeed, why would the treatment be different between 'SELECT' and 'INSERT' for a hibernate native SQL query ?
An HQL INSERT cannot be used to directly insert arbitrary entities—it can only be used to insert entities constructed from information obtained from SELECT queries (unlike ordinary SQL, in which an INSERT command can be used to insert arbitrary data into a table, as well as insert values selected from other tables).
Here’s the syntax of the INSERT statement:
INSERT INTO path ( property [, ...]) select
The name of an entity is path. The property names are the names of properties of entities listed in the FROM path of the incorporated SELECT query. The select query is an HQL SELECT query (as described in the next section).
As this HQL statement can only use data provided by an HQL select, its application can be limited. An example of copying users to a purged table before actually purging them might look like this:
Query query=session.createQuery("insert into purged_accounts(id, code, status) "+
"select id, code, status from acount where status=:status");
query.setString("status", "purged");
int rowsCopied=query.executeUpdate();
Or you can use
session.persist(obj);
where obj is the object of the POJO class let say TestClass
TestClass obj=new TestClass('','',''); //paramatrized constructor for the values you want to insert in your database.

Categories