MyBatis: java.sql.SQLException: 传递给 set 或 update 方法的 java.sql.Types 常量值 -9 无效
MyBatis: java.sql.SQLException: Invalid java.sql.Types constant value -9 passed to set or update method
我在从 MyBatis 调用 SqlServer 中的 Stored_Procedure 时遇到此错误:
> ### Error querying database. Cause: java.sql.SQLException: Invalid java.sql.Types constant value -9 passed to set or update method.
> ### The error may exist in mybatis-mapper/UpstreamMapper.xml
> ### The error may involve callStoredProcedure
> ### The error occurred while executing a query
> ### SQL: {call dbo.get_discount_value(?,?, ?,?,?,?)}
> ### Cause: java.sql.SQLException: Invalid java.sql.Types constant value -9 passed to set or update method.
我是否需要将 Stored_Procedure 中的变量类型与我的 POJO 中的变量类型相匹配?
所以如果这些是 Stored_Procedure 的变量:
CREATE PROCEDURE [dbo].[get_discount_value]
@firstname nvarchar(50),
@lastname nvarchar(10),
@gender nvarchar(1),
@dateOfBirth date,
@age bigint
AS
BEGIN
.. SP BODY..
POJO:StoredProcRef.java
public class StoredProcRef {
String SP_FirstName= "";
String SP_LastName= "";
String SP_Gender = "";
Date SP_Birthday = null;
Integer SP_Age = 0;
String Output = "";
..GETTERS AND SETTERS..
}
MapperXML.xml
<resultMap id = "ReferenceValueParams" type="StoredProcRef" autoMapping="false" >
<result property = "SP_FirstName" column = "SP_FirstName"/>
<result property = "SP_LastName" column = "SP_LastName"/>
<result property = "SP_Gender" column = "SP_Gender"/>
<result property = "SP_Birthday" column = "SP_Birthday"/>
<result property = "SP_Age" column = "SP_Age"/>
<result property = "Output" column = "DiscountValue"/>
</resultMap>
<select id = "callStoredProcedure" statementType = "CALLABLE" resultMap="ReferenceValueParams">
{call dbo.lab_get_result_form_field(
#{SP_FirstName,mode=IN,jdbcType=NVARCHAR},
#{SP_LastName,mode=IN,jdbcType=NVARCHAR},
#{SP_Gender,mode=IN,jdbcType=NVARCHAR},
#{SP_Birthday,mode=IN,jdbcType=DATE},
#{SP_Age,mode=IN,jdbcType=BIGINT},
#{Output,mode=OUT,jdbcType=NVARCHAR}
)}
</select>
Interfacemapper.java
public interface UpstreamXmlMapper {
public List<Map<String, ?>> callStoredProcedure(String FirstName, String LastName, String gender, Date dateOfBirth, Integer age);
}
Service.java
public List<Map<String, ?>> getDiscountValue( StoredProcRef storedProcRef ) {
List<Map<String, ?>> referenceValue = new ArrayList<>();
SqlSession session = MyBatisUtil.getSqlSessionFactory().openSession();
try {
UpstreamXmlMapper applicationMapper = session.getMapper(UpstreamXmlMapper.class);
referenceValue = applicationMapper.callStoredProcedure(storedProcRef.getSP_FirstName(), storedProcRef.getLastName(), storedProcRef.getSP_Gender(), storedProcRef.getSP_Birthday(), storedProcRef.getSP_Age()) ;
session.commit();
} catch (Exception e) {
LOGGER.error(e);
} finally {
session.close();
}
return referenceValue;
}
Main.java
SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
Date date;
date = sdf.parse("01-Oct-1984");
List<StoredProcRef> storedProcRefList = new ArrayList<>();
StoredProcRef storedProcRefObj = new StoredProcRef();
storedProcRefObj.setSP_Age(28);
storedProcRefObj.setSP_Birthday(date);
storedProcRefObj.setSP_Gender("M");
storedProcRefObj.setSP_FirstName("Joe");
storedProcRefObj.setSP_LastName("Higashi");
storedProcRefList.add(storedProcRefObj);
List<Map<String, ?>> referenceValue = new ArrayList<>();
referenceValue = service.getDiscountvalue(storedProcRefList.get(0));
您似乎对输入和输出参数感到困惑。
由于过程声明没有 OUT
参数,结果将映射到不同的对象。
我将使用下面的新 class 进行解释。
public class StoredProcOutput {
private String Output;
// getter/setter
}
由于过程是用五个参数声明的,因此call
语句中应该有五个参数,而不是六个。即
<select id="callStoredProcedure" statementType="CALLABLE"
resultMap="outputResultMap">
{call MY_PROC(
#{SP_FirstName,mode=IN,jdbcType=NVARCHAR},
#{SP_LastName,mode=IN,jdbcType=NVARCHAR},
#{SP_Gender,mode=IN,jdbcType=NVARCHAR},
#{SP_Birthday,mode=IN,jdbcType=DATE},
#{SP_Age,mode=IN,jdbcType=BIGINT}
)}
</select>
结果映射用于映射查询结果(您的过程中有查询,对吗?)。
如你所愿DiscountValue
,很简单
<resultMap id="outputResultMap" type="test.StoredProcOutput">
<result property="Output" column="DiscountValue" />
</resultMap>
您的映射器方法应如下所示:
List<StoredProcOutput> callStoredProcedure(StoredProcInput inParam);
我也更新了演示项目。
https://github.com/harawata/mybatis-issues/tree/master/so-58802623
如果您需要进一步的帮助,我可能会在一段时间内与您聊天(不过我不确定聊天是如何进行的)。
我在从 MyBatis 调用 SqlServer 中的 Stored_Procedure 时遇到此错误:
> ### Error querying database. Cause: java.sql.SQLException: Invalid java.sql.Types constant value -9 passed to set or update method.
> ### The error may exist in mybatis-mapper/UpstreamMapper.xml
> ### The error may involve callStoredProcedure
> ### The error occurred while executing a query
> ### SQL: {call dbo.get_discount_value(?,?, ?,?,?,?)}
> ### Cause: java.sql.SQLException: Invalid java.sql.Types constant value -9 passed to set or update method.
我是否需要将 Stored_Procedure 中的变量类型与我的 POJO 中的变量类型相匹配?
所以如果这些是 Stored_Procedure 的变量:
CREATE PROCEDURE [dbo].[get_discount_value]
@firstname nvarchar(50),
@lastname nvarchar(10),
@gender nvarchar(1),
@dateOfBirth date,
@age bigint
AS
BEGIN
.. SP BODY..
POJO:StoredProcRef.java
public class StoredProcRef {
String SP_FirstName= "";
String SP_LastName= "";
String SP_Gender = "";
Date SP_Birthday = null;
Integer SP_Age = 0;
String Output = "";
..GETTERS AND SETTERS..
}
MapperXML.xml
<resultMap id = "ReferenceValueParams" type="StoredProcRef" autoMapping="false" >
<result property = "SP_FirstName" column = "SP_FirstName"/>
<result property = "SP_LastName" column = "SP_LastName"/>
<result property = "SP_Gender" column = "SP_Gender"/>
<result property = "SP_Birthday" column = "SP_Birthday"/>
<result property = "SP_Age" column = "SP_Age"/>
<result property = "Output" column = "DiscountValue"/>
</resultMap>
<select id = "callStoredProcedure" statementType = "CALLABLE" resultMap="ReferenceValueParams">
{call dbo.lab_get_result_form_field(
#{SP_FirstName,mode=IN,jdbcType=NVARCHAR},
#{SP_LastName,mode=IN,jdbcType=NVARCHAR},
#{SP_Gender,mode=IN,jdbcType=NVARCHAR},
#{SP_Birthday,mode=IN,jdbcType=DATE},
#{SP_Age,mode=IN,jdbcType=BIGINT},
#{Output,mode=OUT,jdbcType=NVARCHAR}
)}
</select>
Interfacemapper.java
public interface UpstreamXmlMapper {
public List<Map<String, ?>> callStoredProcedure(String FirstName, String LastName, String gender, Date dateOfBirth, Integer age);
}
Service.java
public List<Map<String, ?>> getDiscountValue( StoredProcRef storedProcRef ) {
List<Map<String, ?>> referenceValue = new ArrayList<>();
SqlSession session = MyBatisUtil.getSqlSessionFactory().openSession();
try {
UpstreamXmlMapper applicationMapper = session.getMapper(UpstreamXmlMapper.class);
referenceValue = applicationMapper.callStoredProcedure(storedProcRef.getSP_FirstName(), storedProcRef.getLastName(), storedProcRef.getSP_Gender(), storedProcRef.getSP_Birthday(), storedProcRef.getSP_Age()) ;
session.commit();
} catch (Exception e) {
LOGGER.error(e);
} finally {
session.close();
}
return referenceValue;
}
Main.java
SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
Date date;
date = sdf.parse("01-Oct-1984");
List<StoredProcRef> storedProcRefList = new ArrayList<>();
StoredProcRef storedProcRefObj = new StoredProcRef();
storedProcRefObj.setSP_Age(28);
storedProcRefObj.setSP_Birthday(date);
storedProcRefObj.setSP_Gender("M");
storedProcRefObj.setSP_FirstName("Joe");
storedProcRefObj.setSP_LastName("Higashi");
storedProcRefList.add(storedProcRefObj);
List<Map<String, ?>> referenceValue = new ArrayList<>();
referenceValue = service.getDiscountvalue(storedProcRefList.get(0));
您似乎对输入和输出参数感到困惑。
由于过程声明没有 OUT
参数,结果将映射到不同的对象。
我将使用下面的新 class 进行解释。
public class StoredProcOutput {
private String Output;
// getter/setter
}
由于过程是用五个参数声明的,因此call
语句中应该有五个参数,而不是六个。即
<select id="callStoredProcedure" statementType="CALLABLE"
resultMap="outputResultMap">
{call MY_PROC(
#{SP_FirstName,mode=IN,jdbcType=NVARCHAR},
#{SP_LastName,mode=IN,jdbcType=NVARCHAR},
#{SP_Gender,mode=IN,jdbcType=NVARCHAR},
#{SP_Birthday,mode=IN,jdbcType=DATE},
#{SP_Age,mode=IN,jdbcType=BIGINT}
)}
</select>
结果映射用于映射查询结果(您的过程中有查询,对吗?)。
如你所愿DiscountValue
,很简单
<resultMap id="outputResultMap" type="test.StoredProcOutput">
<result property="Output" column="DiscountValue" />
</resultMap>
您的映射器方法应如下所示:
List<StoredProcOutput> callStoredProcedure(StoredProcInput inParam);
我也更新了演示项目。
https://github.com/harawata/mybatis-issues/tree/master/so-58802623
如果您需要进一步的帮助,我可能会在一段时间内与您聊天(不过我不确定聊天是如何进行的)。