Java – the entity manager does not answer until the Native Query call is completed
I used hibernate and Oracle SQL in the project When I call the createnativequery method of the entity manager, the entity manager does not respond to any calls (even from different browsers) until the method returns The query takes a long time, but it is called in the new thread. Why is the entity manager blocked?
Note: when I call the jpql query, the problem disappears
@PersistenceContext private EntityManager entityManager; //blocking other transactions,cannot make any read from the same entityManager until this method is completed. @Transactional(readOnly=true) public void testMethod1(String query) { Query q = entityManager.createNativeQuery(query); // CANNOT SET LOCKMODE because it is not JPQL : q.setLockMode(LockModeType.NONE) //throws exception List<Object[]> result = q.getResultList(); } @Transactional(readOnly=true) public void testMethod2(String jpql) { Query q = entityManager.createQuery(jpql); List<Object> result = q.getResultList(); }
Solution
I can reproduce your problem using other databases (SQL Anywhere in my case)
After that, I looked at hibernate JavaDocs and it said that your problem is the default behavior, because JPA requires setlockmode to be applied only to non-native queries
To solve this problem, hibernate uses the queryhints of the query:
NATIVE_ Lockmode: lock mode can be applied to native SQL queries because JPA requires query Setlockmode (javax. Persistence. Lockmodetype) throws an IllegalStateException when calling a native query
To use queryhints, you should do the following:
@Transactional(readOnly=true) public void testMethod1(String query) { Query q = entityManager.createNativeQuery(query); q.setHint(QueryHints.NATIVE_LOCKMODE,LockModeType.NONE); List<Object[]> result = q.getResultList(); }
I also found that if you use @ transactionattribute on the method, the problem may not occur, for example:
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) public void testMethod1(String query) { Query q = entityManager.createNativeQuery(query); q.setHint(QueryHints.NATIVE_LOCKMODE,LockModeType.NONE); List<Object[]> result = q.getResultList(); }
Please try the solution given above. If the problem is solved, please tell us and wish you good luck!