2017-04-18 221 views
0

我读过休眠4.0直到4.1.3在关闭连接或执行语句后出现了未释放/释放(我没有精通数据库管理)OracleSql游标的问题。 尽管我已经增加了DataBase上的最大游标,但直到再次达到游标的最大数量只是时间问题。我很确定这是问题所在,因为构建失败,而不是在运行特定的测试或测试类时。
它仍然是一个已知的问题休眠5?如果是的话,我该如何手动释放游标?
我使用,清酒Ø完整性:
- Hibernate的核心-5.0.11 - 从我读过这应该处理 光标
- 的Hibernate的EntityManager-5.0.11
- 休眠,JPA -2.1-API-1.0.0
- Oracle数据库11.2.0.1如何使用Hibernate自动释放游标?

那(我想)引起的问题:

package org.mypackage.status; 
import java.util.stream.Stream; 
import org.mypackage.entity.status.Status; 
import org.mypackage.entity.status.StatusContract; 
import org.springframework.data.jpa.repository.Query; 
import org.springframework.data.repository.CrudRepository; 

public interface StatusContractRepository extends CrudRepository<StatusContract, Long>{ 
    @Query("select cs from StatusContract cs") 
    Stream<StatusContract> streamAll(); 

    @Query("select cs from StatusContract cs where cs.name=?1") 
    StatusContract findOneByName(final Status name); 
} 

服务功能,我测试和使用上述):

@Service 
public class StatusService { 

    private final StatusContractRepository statusContractRepository; 
    private final ContractRepository contractRepository; 

    public StatusService(final StatusContractRepository statusContractRepository, final ContractRepository contractRepository) { 
     this.statusContractRepository = Objects.requireNonNull(statusContractRepository, "statusContractRepository must not be null."); 
     this.contractRepository = Objects.requireNonNull(contractRepository, "contractRepository must not be null."); 
    } 

    public String setContractStatus(final DocComm lastDocComm) {   
     Contract contract = lastDocComm.getContract(); 

     if (lastDocComm.getAnswer() != null) { 
      switch (lastDocComm.getAnswer().getDocumentType().getCode()) { 
       case DocumentType.A_REQ_CLARIFY: 
        contract.setStatus(statusContractRepository.findOneByName(Status.CLAR_RECEIVED)); 
        break; 
       case DocumentType.A_REQ_DOC_ADDITIONAL: 
        contract.setStatus(statusContractRepository.findOneByName(Status.CLAR_RECEIVED)); 
        break; 
       // there are more cases; they have the same behavior 
       default: 
        break; 
      } 
     } else if (lastDocComm.getRequest() != null) { 
      switch (lastDocComm.getRequest().getDocumentType().getCode()) { 
       case DocumentType.REQ_TERMS: 
        contract.setStatus(statusContractRepository.findOneByName(Status.REQ_TERM)); 
        break; 
       case DocumentType.REQ_MODIFY: 
        contract.setStatus(statusContractRepository.findOneByName(Status.REQ_MODIFY)); 
        break; 
       // there are more cases; they have the same behavior 
       // the first few calls are alright, or when I run specifically one call 
       // the problem occurs at build when it calls all the functions 
       default: 
        break; 
      } 
     } 
     contractRepository.save(contract); 
     return contract.getStatus().getFullName(); 
    } 
} 

登录从NetBeans中:

testChangeStatus_1 
[WARN ] 2017-04-18 09:07:13 [o.h.e.j.s.SqlExceptionHelper:127]- SQL Error: 604, SQLState: 60000 
2017-04-18 09:07:13 [o.h.e.j.s.SqlExceptionHelper:129]- ORA-00604: error occurred at recursive SQL level 1 
ORA-01000: maximum open cursors exceeded 
ORA-01000: maximum open cursors exceeded 

[INFO ] 2017-04-18 09:07:13 [o.h.e.i.DefaultLoadEventListener:129]- HHH000327: Error performing load command : org.hibernate.exception.GenericJDBCException: could not extract ResultSet 
[INFO ] 2017-04-18 09:07:13 [o.h.e.i.DefaultLoadEventListener:129]- HHH000327: Error performing load command : org.hibernate.exception.GenericJDBCException: could not extract ResultSet 
[INFO ] 2017-04-18 09:07:13 [o.h.e.i.DefaultLoadEventListener:129]- HHH000327: Error performing load command : org.hibernate.exception.GenericJDBCException: could not extract ResultSet 
[INFO ] 2017-04-18 09:07:14 [o.m.a.AbstractEntityListener:63]- DECLARE return_code number; BEGIN SP_STERGE_INREGISTRARE ('COMMUNICATION_DOC',6515, 'null', to_date('2017-04-18','YYYY-mm-dd'), 'FO', return_code); END; 
[INFO ] 2017-04-18 09:07:14 [o.m.a.AbstractEntityListener:67]- SQL_CALL_RESULT: 1 
[INFO ] 2017-04-18 09:07:14 [o.m.a.AbstractEntityListener:63]- DECLARE return_code number; BEGIN SP_STERGE_INREGISTRARE ('CONTRACT',9824, 'null', to_date('2017-04-18','YYYY-mm-dd'), 'FO', return_code); END; 
[INFO ] 2017-04-18 09:07:14 [o.m.a.AbstractEntityListener:67]- SQL_CALL_RESULT: 1 
[INFO ] 2017-04-18 09:07:14 [o.m.a.AbstractEntityListener:63]- DECLARE return_code number; BEGIN SP_STERGE_INREGISTRARE ('DOCUMENT',21551, 'null', to_date('2017-04-18','YYYY-mm-dd'), 'FO', return_code); END; 
[INFO ] 2017-04-18 09:07:14 [o.m.a.AbstractEntityListener:67]- SQL_CALL_RESULT: 1 
[INFO ] 2017-04-18 09:07:14 [o.m.a.AbstractEntityListener:63]- DECLARE return_code number; BEGIN SP_STERGE_INREGISTRARE ('DOCUMENT',21552, 'null', to_date('2017-04-18','YYYY-mm-dd'), 'FO', return_code); END; 
[INFO ] 2017-04-18 09:07:14 [o.m.a.AbstractEntityListener:67]- SQL_CALL_RESULT: 1 
testChangeStatus_2 
[WARN ] 2017-04-18 09:07:14 [o.h.e.j.s.SqlExceptionHelper:127]- SQL Error: 604, SQLState: 60000 
2017-04-18 09:07:14 [o.h.e.j.s.SqlExceptionHelper:129]- ORA-00604: error occurred at recursive SQL level 1 
ORA-01000: maximum open cursors exceeded 
ORA-01000: maximum open cursors exceeded 
... 

这正好为许多其他测试功能。
如果有任何需要进一步的细节,我会匆匆提供它们。

回答

0

可否请您提供使用DB游标的JPA/Hibernate代码。我认为你应该在Java代码中调用close()方法(可能在org.hibernate.ScrollableResults)来关闭游标对象。

+0

我正在使用Controller - Service - Repository架构。 目前正在测试**服务**功能,不需要测试存储库,_Hibernate_:insert,listAll等。当然,还有自定义的findByMyCustomField和特定的@Query 我应该提供哪些代码部分?服务或存储库?我这样问是因为我认为如果只说应该提供存储库,我会更好地理解这个问题。 –

+0

我误解了您的请求。我没有使用任何光标对象本身。我们只有一堆由服务使用的存储库。从我读过的内容来看,_Hibernate_不会显式关闭/释放执行语句时自动获取的游标。 –

+0

你可以发布那些与数据库游标一起工作的代码吗?无论是Java库类还是某些数据库过程语言调用。你也可以检查与游标一起工作的代码是否正确释放游标? – bbelovic