【发布时间】:2016-10-06 18:50:35
【问题描述】:
我正在使用 Spring Data JPA 1.10.2 和 jTds 1.3.1 来调用存储过程。
存储过程有一个输出参数,@data,类型为 varbinary(max)。 @data 包含约 10,000 个字节。
这是存储过程的签名:
ALTER procedure [User].[pTest]
@data varbinary(max) out
,@name nvarchar(max) = null
,@date datetime
as
begin
.
.
.
我的实体类是:
@Entity
@NamedStoredProcedureQuery(name = "User.getUser", procedureName = "User.pTest", parameters = {
@StoredProcedureParameter(mode = ParameterMode.OUT, name = "data", type = byte[].class),
@StoredProcedureParameter(mode = ParameterMode.IN, name = "name", type = String.class),
@StoredProcedureParameter(mode = ParameterMode.IN, name = "date", type = Date.class)
})
@Data //lombok
public class User {
// serves no purpose other than to meet
// JPA requirement
@Id
private Long id;
}
仓库代码是
public interface UserRepository extends Repository<User, Long> {
@Procedure("User.pTest")
byte[] getUserSession(@Param("name") String name,
@Param("date") Date date
);
}
我的测试代码如下,运行时出现错误:
@Test
public void testGettingApxSession() {
Calendar cal = new GregorianCalendar(2016,6,5);
byte[] b = userRepository.getUserSession("myName", cal.getTime());
}
当我使用以下方式注销@data 时:
StringBuilder sb = new StringBuilder();
for (byte a : b) {
sb.append(String.format("%02X ", a));
}
我注意到只返回了 8,000 个字节。当我在 SQL Server Management Studio 中运行相同的存储过程时,我注意到它有大约 10,000 个字节并以十六进制代码 FFFF 结束。
因此,从我的 Java 应用程序运行存储过程时,我的结果似乎被截断了。
如何防止这种截断?我应该为 varbinary(max) 而不是 byte[] 指定不同的数据类型吗?
更新
我也尝试过 Microsoft 的 JDBC 驱动程序 (v 6.0.7728.100) 并遇到同样的问题。我的猜测是 JDBC 驱动程序(我认为)基于最大数 n 将最大值设为 8000,您可以在 varbinary(n) 中指定。但是,varbinary 的最大容量远大于 8000,由varbinary(max) 指定。 varbinary(max) 可以容纳 2^31 - 1 个字节。查看我的问题和其他人的答案here
【问题讨论】:
-
8000 字节听起来很熟悉。我建议像风一样使用谷歌搜索。
-
我试过了。似乎找不到任何确定的东西
-
经过相当多的研究,它似乎是一个超过 2 年的错误。我希望我错了,它已经解决了。这是致命的问题。我不能使用 Microsoft SQL Server 驱动程序 b/c 它有自己的致命问题,即必须使用非空值声明默认参数。
-
我在sourceforge.net/p/jtds/bugs/766提交了一个错误报告
-
它发现 Microsoft 的 SQL Server JDBC 驱动程序表现出相同的行为(即它在 8000 字节处截断)。 SQL Server 过去对
varbinary最多有 8000 个字节。我想这些 SQL Server JDBC 驱动程序从未更新以考虑增加的大小。
标签: sql-server jpa jdbc spring-data-jpa jtds