如何使用Hibernate自动释放游标?

时间:2017-04-18 07:36:31

标签: java cursor oracle-sqldeveloper hibernate-5.x

我已经读过 hibernate 4.0 直到 4.1.3 在关闭之后没有释放/解除分配(我不精通数据库管理)OracleSql游标的问题连接或执行语句后。 虽然我已经增加了DataBase上的最大游标,但是再次达到最大游标数只是时间问题。我很确定这是问题所在,因为构建失败而不是在运行特定的测试或测试类时 它仍然是 Hibernate 5 中的已知问题吗?如果是,我如何手动释放游标?
为了完整起见,我正在使用:
  - Hibernate-core-5.0.11 - 从我读过的内容来看,应该处理这个问题    游标
  - Hibernate-entitymanager-5.0.11
  - Hibernate-jpa-2.1-api-1.0.0
  - Oracle数据库11.2.0.1

存储库我想)会导致问题:

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
...  

这继续了许多其他测试功能 如果需要进一步的细节,我会匆匆提供。

1 个答案:

答案 0 :(得分:0)

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