gpt4 book ai didi

java - 实体管理器在 native 查询调用结束之前不回答

转载 作者:搜寻专家 更新时间:2023-11-01 03:49:03 26 4
gpt4 key购买 nike

我在项目中使用 Hibernate 和 Oracle SQL。当我调用实体管理器的 createNativeQuery 方法时,实体管理器在方法返回之前不应答任何调用(即使来自不同的浏览器)。查询需要很长时间,但它是在新线程中调用的。为什么实体管理器被阻止?

注意:当我调用 JPQL 查询时,问题消失了。

@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();
}

最佳答案

我能够使用其他数据库(在我的例子中是 SQL Anywhere)重现您的问题。

之后我看了看Hibernate JavaDocs它说你的问题是默认行为,因为 JPA 要求 setLockMode 应该只应用于非 native 查询。

为了解决这个问题,Hibernate 使用查询的 QueryHints:

NATIVE_LOCKMODE:可用于将锁定模式应用于 native SQL 查询,因为 JPA 要求 Query.setLockMode(javax.persistence.LockModeType) 在为 native 查询调用时抛出 IllegalStateException。

要使用 QueryHints,你应该这样做:

@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();
}

我还发现,如果您在方法上方使用 @TransactionAttribute,问题可能不会发生,例如:

@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();
}

请尝试上面给出的解决方案,让我们知道问题是否已解决,祝您好运!

关于java - 实体管理器在 native 查询调用结束之前不回答,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33693802/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com