We've got the following DAO stack:
DB2 9.7 Express-C
OpenJPA 2.0.1
Spring 3.0.5
Bitronix 2.1.1
How do you specify OpenJPA to add WITH UR sql clause to the end of the query?
I'd browsed sites and manuals alike for days, it should be something like this:
Query q = em.createQuery("select m from Magazine m where ... ");
q.setHint("openjpa.FetchPlan.ReadLockMode","WRITE");
List r = q.getResultList();
but alas, I've been unable to find a working OpenJPA property that would be passed as setHint() argument and yield WITH UR as result, so I use SpringJDBC queries which I unfortunately can't use any longer.
Any ideas? Thank you very much
OpenJPA doesn't support using the WITH UR clause with JPQL. You could always use a native query for this functionality.
I'm having quite a similar problem now — it would seem that setting:
query.setHint("openjpa.FetchPlan.Isolation", "READ_UNCOMMITTED");
would do the trick. Unfortunately, the source code reveals that the constant withURClause from org.apache.openjpa.jdbc.sql.DB2Dictionary is never read.
Additionally OpenJPA never takes into account a fetch plan hint if the query is not FOR UPDATE. I have a select statement that gets blocked on exclusive locks and it could really work with uncommitted data — a no-go with OpenJPA.
Related
I have a question. Where did these methods go?
Dialect.supportsTemporaryTables();
Dialect.generateTemporaryTableName();
Dialect.dropTemporaryTableAfterUse();
Dialect.getDropTemporaryTableString();
I've tried to browse git history for Dialect.java, but no luck. I found that something like
MultiTableBulkIdStrategy was created but I couldn't find any example of how to use it.
To the point...I have legacy code (using hibernate 4.3.11) which is doing batch delete from
multiple tables using temporary table. In those tables there may be 1000 rows, but also there may
be 10 milion rows. So just to make sure I don't kill DB with some crazy delete I create temp table where I put (using select query with some condition) 1000 ids at once
and then use this temp table to delete data from 4 tables. It's running in while cycle until all data based on some condition is not deleted.
Transaction is commited after each cycle.
To make it more complicated this code has to run on top of: mysql, mariadb, oracle, postgresql, sqlserver and h2.
It was done using native SQL, with methods mentioned above. But not I can't find a way how
to refactor it.
My first try was to create query using nested select like this:
delete from TABLE where id in (select id from TABLE where CONDITION limit 1000) but this is way slower as I have to run select query multiple times for each delete and limit is not supported in nested select in HQL.
Any ideas or pointers?
Thanks.
The methods were present in version 4.3.11 but removed in version 5.0.0. It seems a bit unusual that they were removed rather than deprecated - the background is on this Jira ticket.
To quote from this:
Long term, I think the best approach is to remove the Dialect method
intended to support table tabled in a piecemeal fashion and to make
MultiTableBulkIdStrategy be a fully self-contained contract.
The methods were removed in this commit.
So it seems that getDefaultMultiTableBulkIdStrategy() is the intended replacement for these methods - but I'm not entirely clear on how, as it currently has no Javadoc. Guess you could try to work it out from the source code ...or if all else fails, perhaps try to contact Steve Ebersole, who implemented the change?
I have a question, would like to get some help with.
I have the query running from Java.
SELECT DISTINCT field1, field1
from tblTableA WITH (NOLOCK)
WHERE criteriaField='CONSTANT TEXT'
I run it with jpa
Query qry = entMgr.createNativeQuery(myQry) ;
List sqlResult = qry.getResultList() ;
Now, that qry.getResultList() takes too much time to run - 75 or more seconds. Yes, it returns close to 700 000 records, but the same query ran on Weblogic 10, using ejb2 runs in less than 5 seconds time
Can anyone help resolving this issue, seems like there maybe a configuration I am missing, or a technique I am not following.
There is something on account of using
jbosscmp-jdbc.xml.
I don't have that in my set up, but found out that there is a lazy-loading feature that we can configure. Now, I am not sure how make the query I am running be configured in xml file.
Also, can this be used with annotations instead of xml file ?
I would try to run this query inside of a non-transactional method:
#TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
List getResults(..){
Query qry = entMgr.createNativeQuery(myQry) ;
return qry.getResultList() ;
}
This is sometimes not allowed depending on the environment and is mainly used for the optimization of queries expecting to have large results sets and which would later be managed by the PersistenceContext (so basically when you would use HQL instead of native)
But i would give it a try.
You are performing this select query within a transaction scope. I found an old JIRA ticket on Jboos's site. As the ticket suggests, there is a potential around the flush. If you perform a query with EJB3, a flush is performed or attempted automatically for all the objects you retrieve with your native query. The idea seems to be avoid getting stale objects from the database. But in your case, it is not applicable. Set the flush mode to COMMITand see if the performance improves.
query.setFlushMode( FlushModeType.COMMIT );
Also turn off the Hibernate logging and see if that makes any difference.
I know case can be used as expression in where clause of HQL.
I read through this thread Using a CASE statement in HQL select
In a way my question is duplicate
Is it possible to use them in the select part of HQL with hibernate 4 or 5. I know its not possible with Hibernate 3.
Yes it is.
There is a dedicated section in the Hibernate 5 Documentation you can take a look as well as in this section for Hibernate 4.3.
According to the changelog.txt it was added back in version 3.0 though not in the form it has evolve to today (SimpleCaseExpression, SearchedCaseExpression)
I have a query which has 2 'in' Clauses. First in clause takes around 125 values and second in clause of query takes around 21000 values. Its implemented using JPA CriteriaBuilder.
Query itself executes very fast and return results within seconds. Only problem is entityManager.createQuery(CriteriaQuery) takes around 12-13 minutes to return.
I search all over SO, all the threads are related to performance of Query.getResultList. None of them discuss about performance of entityManager.createQuery(CriteriaQuery). If you have seen such behavior earlier, please let me know, how to resolve it.
My JDK version is 1.7. Dependency version of javaee-api is 6.0. Application is deployed on JBOSS EAP 6.4. But that's not the concern as of now, as I am testing my code using junit using EntityManager connected to actual Oracle database. If you require more information, kindly let me know.
A hybrid approach is to dynamically create a query and then save it as a named query in the entity manager factory.
At that point it becomes just like any other named query that may have been declared statically in metadata. While this may seem like a good compromise, it turns out to be useful in only a few specific cases. The main advantage it offers is if there are queries that are not known until runtime, but then reissued repeatedly. Once the dynamic query becomes a named query it will only bear the cost of processing once.
It is implementation-specific whether that cost is paid when the query is registered as a named query, or deferred until the first time it is executed.
A dynamic query can be turned into a named query by using the
EntityManagerFactory addNamedQuery()
Keep us informed by the result and good luck
I observed that, having single query with 21 IN clauses (each with 1000 expressions) and all combined with OR clauses, made query run slower. I tried another approach of executing every IN Clause as a part of separate query. So these 21 individual queries performed better overall.
Another issue I observed was that Query with CriteriaBuilder was slow when result set is huge (something like 20K rows in result set). I solved this issue by adding query hint to my typed query:
TypedQuery.setHint("org.hibernate.fetchSize", 5000);
Hope it will help others.
Code in Hibernate is not expected to be used for binding lots of params:
for ( ImplicitParameterBinding implicitParameterBinding : parameterMetadata.implicitParameterBindings() ) {
implicitParameterBinding.bind( jpaqlQuery );
}
Unfortunately you need to find different approach if you want to do something similar.
We are using Hibernate with IBM DB2 9.7. The database gives error about Hibernate generated too large select statement list (including a lot of joins). The error code is 840. Can something be done to fix this? I know the generated select list is very long, but can Hibernate be set to split it into parts or something?
Edit: I reopened this since the problem seems to be a bit larger. So there is a JIRA issue (now rejected) at https://hibernate.onjira.com/browse/ANN-140.
So the problem is that with Hibernate Annotations, it is not possible to add discriminator with Join strategy. XML configuration however does support this.
Pavel nicely states the problem in the above link discussion like this:
"It would be nice to see how the problem with the multiple joins is faced when the
underlying DB has restriction on the number of joins one can execute in a single SQL?
For instance MySQL seems to allow only 31 joins. What happens if the class hierarchy
has more than 31 sub-classes?"
An the above is the very problem I am having. We are using annotations and the subclasses are quite a few, creating massive amounts of joins, breaking the DB2 statement.
Any comments on this? I could not find a direct solution either.
Hibernate has few fetching strategies to optimize the Hibernate generated select statement, so that it can be as efficient as possible. The fetching strategy is declared in the mapping relationship to define how Hibernate fetch its related collections and entities.
Fetching Strategies
There are four fetching strategies
fetch-”join” = Disable the lazy loading, always load all the collections and entities.
fetch-”select” (default) = Lazy load all the collections and entities.
batch-size=”N” = Fetching up to ‘N’ collections or entities, Not record.
fetch-”subselect” = Group its collection into a sub select statement.
For detail explanation, you can check on the Hibernate documentation.