在本机查询调用结束之前,Entitiy Manager不会应答

时间:2015-11-13 13:27:02

标签: java sql oracle hibernate jpa

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

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

select * from
(
SELECT DISTINCT
    concat([Segment_0], '-' , [Segment_1], '-',[Segment_2])  As 'AcctCode',
    T1.[AcctName] as dummyname1,
    T2.[Name]  as dummyname2,
    concat(T3.[Code],'-',T3.[Name]) as dummyname3,
    T0.[DebLTotal] AS 'ANNUAL BUDGET',
    (SELECT concat(T3.Code , '-', T3.[Name]) where T3.SegmentId = '1') AS 'Project',
    (SELECT concat(T3.Code , '-', T3.[Name]) where T3.SegmentId = '2') AS 'Distt'
FROM OBGT T0
INNER JOIN OACT T1
    ON T0.[AcctCode] = T1.[AcctCode]
INNER JOIN OBGS T2
    ON T0.[Instance] = T2.[AbsId] 
INNER JOIN OASC T3
    ON (T3.SegmentId = '1' AND T3.Code = [Segment_1])
    OR (T3.SegmentId = '2' AND T3.Code = [Segment_2])
) dt
where Project = 100 and Distt =001

1 个答案:

答案 0 :(得分:0)

我能够使用其他数据库(在我的情况下为SQL Anywhere)重现您的问题。

在此之后,我查看了Hibernate JavaDocs并且它说您的问题是默认行为,因为JPA要求setLockMode应仅应用于非本机查询。

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

<强> NATIVE_LOCKMODE : 可以将锁定模式应用于本机SQL查询,因为JPA要求Query.setLockMode(javax.persistence.LockModeType)在调用本机查询时抛出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();
}

请尝试上面给出的解决方案,如果问题解决了,请告诉我们,祝你好运!