specify query timeout when using toplink essential query hint - java

For glassfish v2, I have searched through the web and I cannot find anyway to specify query timeout when using TopLink essential query hint. We have another option to migrate to EclipseLink but that is not feasible.
have tried the solution in
http://forums.oracle.com/forums/thread.jspa?threadID=974732&tstart=-1
but it seems the DatabaseQuery which one could set a timeout value is actually for Toplink, not TopLink essential.
Do we have some other way to instruct the JDBC driver for this timeout value other than the query hint? I need to do it on query-basis and not system-basis (which is just to change the value of DISTRIBUTED_LOCK_TIMEOUT)

According to the documentation of Toplink JPA about Query Hints:
You can use the following TopLink JPA
hints (for more details on these
settings please refer to the TopLink
documentation)
fetchSize Takes an Integer. Allows
the user to set the fetchSize of a
TopLink query.
referenceClass Takes
a class. Override the target class of
the query.
cacheUsage Takes an
Integer. Describes how TopLink makes
use of the cache for querying objects.
refresh Takes a Boolean. Set to true if the cache should be refreshed from
the database.
lockMode Takes an
Integer. Set for Pessimistic Locking.
expression Takes a TopLink Expression object. Used for querying
using TopLink API.
timeout Takes an
Integer. Sets the the query timeout in
milseconds.
So my understanding is that you should be able to do that:
Query queryEmployeesByFirstName = em.createNamedQuery("findAllEmployeesByFirstName");
queryEmployeesByFirstName.setHint("timeout", new Integer(5000));
Not tested though.

Related

Avoiding repeated Data Base calls for the same parameters using Java 8 or Spring data JPA

I am having a data base call which is in Oracle and i am using Spring data JPA for that.
I do have a function which utilizes this db call to retrieve the result every time in the loop.
Now my problem is most of the time the combination of parameter values are repeating. How to avoid this and is there a way to store temporarily for the given set of combination and the corresponding result set without any caching mechanism.
Any luck in Java 8 or spring data JPA itself?.
You have various options.
If you are using Hibernate you may use it's query cache: https://vladmihalcea.com/how-does-hibernate-query-cache-work/ I'm not sure if EclipseLink has a similar feature.
You may use Springs caching facility. https://spring.io/guides/gs/caching/
And of course you may role your own by assembling all the parameters in a single object with proper equals and hashCode implementation and store the result in a HashMap

About JPA NamedNativeQuery compilation

Are sql queries specified inside #NamedNativeQuery pre-compiled just like #NamedQuery in JPA? I am asking this because I couldn't find anything stating it is or it isn't.
#NamedQuery "pre-compilation" is basically translating in advance to the native query language (typically SQL), so you can do it just once at application start / first use and not every time you issue the query.
#NamedNativeQuery queries are written in the native query language already, so in this sense, they are "intrinsically" precompiled.
The amount of pre-processing done to the queries annotated with #NamedNativeQuery is dependent on the JPA Provider, however you shouldn't assume much is happening, since the query is native to the underlying database, so nothing is happening at the JPA level. This is especially the case if you are calling stored procedures or something very database specific JPA is not aware of. There is no translation from JPQL to SQL.
What might go on underneath the hood is some optimisations around prepared statements for those named queries. But it depends on the JPA provider and its level of interaction with the JDBC driver of your specific database.

Spring boot + Hibernate + SqlAzure pagination issue

I have a java spring boot application that use hibernate as ORM. The database is an Azure SQL Server.
I've enabled the setShowSql on vendor adapter configuration.
When I want to find objects, I used the TypedQuery's methods setFirstResult and setMaxResults and than invoke the getResultList method.
The query printed in the console doesn't contains the OFFSET and ROW FETCH clauses and it seems that Hibernate first retrieve all result and than apply the pagination on the resulted list.
This obviously causes performance issues.
Where am I doing wrong?
Below I report the sample code I used.
query.setFirstResult(pageable.getOffset());
query.setMaxResults(pageable.getPageSize());
...
query.getResultList()
The only time Hibernate will explicitly include the OFFSET and FETCH clauses under a SQL Server dialect will be when the following conditions are met:
You must use org.hibernate.dialect.SQLServer2012Dialect or any future 2012+ version.
Your query must include an ORDER BY clause.
Your query is not executing a TOP clause query.
The SQLServer2012Dialect uses a customized LimitHandler implementation called SQLServer2012LimitHandler that you can see here that explicitly handles this use case or otherwise falls back to the old behavior.
If both of the requirements above are being met but the logic is still fallig back to the old behavior for some reason, then it's a bug. In that case, you probably should update HHH-12152 with a test case so we can fix it.

Replace single entity in query cache from JPA/Hibernate/EclipseLink?

We need to cache the results of a query; the query returns the whole table of a database. The problem is that the database is changed externally by other application; the Java application making the query is notified with the exact primary key of the row changed.
Is it possible to replace only the changed element from the query cache, not the whole list?
Is this the 1st level cache (from EntityManager) 2nd level Cache (from EntityManagerFactory) or a different cache?
If it is possible can this be done from JPA?
entityManager.refersh(entity);
or is this query cache the 2nd level JPA cache:
entityManagerFactory.getCache().evict(cls, primaryKey);
or only possible through Hibernate/EclipseLink API?
If is not possible, in order to achieve this, would calling entityManager.find() on all elements do it?
I haven't find anything useful neither in Hibernate documentation nor in EclipseLink documentation. Hibernate supports regions and refreshing only regions, but we need entity-level refresh granularity.
Later edit to clarify my findings.
Following the link posted by #Chris in the comment I have found out that what I wanted is actually supported by EclipseLink but only for Oracle Database (there is possible to implement own handler for other vendors; but the call from database is not standardized and differs from vendor to vendor). I have not found if Hibernate supports this or not.
Anyhow the query cache from EclipseLink had some very poor performance compared with Spring Cache (based on CocurrentMap) or with custom based cache so will remain with Spring Cache or Custom Cache over Spring Jdbc.
EntityManager.refresh() is what you want - it refreshes the entity from what is in the database. This should also update the entity in the shared cache if you are not in a transaction, otherwise you may need to use the entityManagerFactory.getCache().evict(cls, primaryKey); as well to clear the second level shared cache so it can be read into it as well later on.

Using Spring's JDBC support to get output parameters

I'm using Spring's JDBC support to run SQL queries and updates on an Oracle database. I'd like to insert a row and then get the key that it was assigned (using an Oracle sequence). In normal JDBC code, I would include a RETURNING INTO clause and then register an output parameter (well described here)
However, I would like to just use Spring to handle all my JDBC work for me. For non-insert SQL statements, I'm currently using a MapSqlParameterSource object and registering all my input parameters. Can I also register an output parameter like this and have it returned to me? I looked over the Chapter 11 portion of the Spring docs, and I saw there was support for an output parameter if I'm using stored procedures, but I would like to avoid doing that if possible. Thanks.
I don't think the Spring JDBC support API provides explicit support for OUT parameters, so you may need to step back a bit and use the more general query API provided by JdbcTemplate:
Object execute(PreparedStatementCreator psc, PreparedStatementCallback action)
This lets you perform arbitrary JDBC operations within the scope of a Spring-managed connection and PrepatedStatement. The downside is that the handling and tidyup of things like ResultSets becomes your problem.
Check out this code - it may do what you want, not sure if Oracle supports this syntax though.
getReturnedGeneratedKeys() Spring JDBC Excample

Categories