我已经读过 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
...
这继续了许多其他测试功能 如果需要进一步的细节,我会匆匆提供。
答案 0 :(得分:0)
请你提供使用DB游标的JPA / Hibernate代码。我认为您应该在Java代码中调用close()
方法(可能在org.hibernate.ScrollableResults
上)来关闭游标对象。