提问人:James 提问时间:9/30/2023 最后编辑:James 更新时间:9/30/2023 访问量:37
Spring Data - 从 Blob 读取字节时关闭的可调用语句
Spring Data - Callable statement being closed while reading bytes from a Blob
问:
背景
我有一个 Spring Boot 3.0 应用程序,它使用 Spring Data JPA 来调用存储过程。下面是调用存储过程的 Spring Data 存储库:
public interface CarRepository extends Repository<Car, Long> {
@Procedure(value="pValuation", outputParameterName="reportData")
Blob getReportData(String carTypes, LocalDate tradeDate);
存储过程位于 SQL Server 2016 数据库中:
CREATE PROCEDURE [dbo].[pValuation]
@carTypes nvarchar(max),
@tradeDate datetime,
@reportData varbinary(max) out
AS
BEGIN
EXEC RDO.pValuation
@reportData = @reportData out,
@CarTypes = @carTypes ,
@Date = @tradeDate,
@IncludeBaseData = true
END
我使用 a 而不是 a 作为 out 参数,因为Blob
byte[]
varbinary(max)
- MS SQL JDBC 驱动程序(版本 mssql-jdbc-11.2.3.jre17)在使用时返回最大 8000 字节,并且
byte[]
- 我的存储过程返回 > 8000 字节
我需要将其转换为字节数组以进行其他处理:Blob
@Service
@RequiredArgsConstructor
@Slf4j
public class CarService {
private final CarRepository carRepository;
public Set<CarDto> getValuations(LocalDate date) {
Blob reportData = carRepository.getReportData("sedan,truck", date);
log.debug("got Blob");
try {
byte[] b= reportData.getBytes(1, (int) reportData.length());
log.debug("exception thrown from line above... will never log this");
return carRepository.getCarValuations(b);
}
catch (SQLException convertBlobToBytesException) {
log.error(convertBlobToBytesException.toString());
}
}
问题
转换为 via the line 时:Blob
byte[]
reportData.getBytes(1, (int) reportData.length())
抛出 A。打开MSSQL JDBC跟踪日志记录后,我发现该语句在获取后立即关闭(即在执行此操作后立即关闭:)。日志如下:SQLExcpetion
Blob
Blob reportData = carRepository.getReportData("sedan,truck", date);
2023-09-29T17:33:05.762-05:00 调试 29104 --- [http-nio-8080-exec-1] c.m.s.jdbc.internals.SQLServerException : *** SQLException:SQLServerCallableStatement:119 com.microsoft.sqlserver.jdbc.SQLServerException:语句为 闭。该语句已关闭。
2023-09-29T17:33:05.771-05:00 错误 29104 --- [http-nio-8080-exec-1] com.example.service.CarService:得到 Blob
然后,日志来自报告关闭输入流、关闭输出流,然后关闭 TCP 套接字。由于调用 尝试从此闭合流中读取字节,因此会出现如下错误:TDS.Channel
reportData.getBytes
2023-09-29T17:33:05.773-05:00 错误 29104 --- [http-nio-8080-exec-1] com.example.service.CarService: com.microsoft.sqlserver.jdbc.SQLServerException:TDS 协议 流无效。
问题
如何使用 Spring Data JPA 从 Blob 中获取字节?
我试过什么
我尝试将方法包装在事务中,但这会导致应用程序在从存储过程调用中读取数据包时挂起。getValuations
我可以在不使用 Spring Data JPA 的情况下获取字节,如下所示:
@Service
@RequiredArgsConstructor
@Slf4j
public class CarService {
private final CarRepository carRepository;
private final EntityManager em;
public Set<CarDto> getValuations(LocalDate date) {
StoredProcedureQuery q = em.createStoredProcedureQuery("pValuation");
q.registerStoredProcedureParameter("carTypes", String.class, ParameterMode.IN);
q.registerStoredProcedureParameter("tradeDate", LocalDate.class, ParameterMode.IN);
q.registerStoredProcedureParameter("reportData", Blob.class, ParameterMode.OUT);
q.setParameter("carTypes", "sedan,truck");
q.setParameter("tradeDate", date);
q.execute();
Blob reportData = (Blob) q.getOutputParameterValue("reportData");
log.debug("got Blob");
try {
byte[] b= reportData.getBytes(1, (int) reportData.length());
log.debug("got bytes");
return carRepository.getCarValuations(b);
}
catch (SQLException convertBlobToBytesException) {
log.error(convertBlobToBytesException.toString());
}
}
这段代码有效,但我想知道如何使用 Spring Data JPA 做到这一点。
答: 暂无答案
评论