본문 바로가기
SpringBoot

[Spring Boot][Error] org.apache.ibatis.binding.BindingException

by 청양호박이 2019. 12. 1.

API는 언뜻보면 참 간단해 보이는 구조이지만, 내부적으로 하나라도 엉키면 아무것도 동작하지 않습니다. 이번에는 여러가지 error중 한가지를 보도록 하겠습니다.

 

[Error]

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.BindingException: Parameter 'mydto' not found. Available parameters are [smDTO, stationName, param1, param2]] with root cause

 

아무리 살펴봐도 난 잘못된게 없는데, 도데체 에러가 왜 발생하는지 모르겠다... mydto는 무엇이며, 난 parameter로 다 넣었는데 뭐가 문제라는거야?? test 예제는 아래와 같습니다.

 

[Mapper.java]

@Mapper
public interface UserMapper {

	ArrayList<UserDTO> selectUser();

	ArrayList<StationMiseDTO> selectStationMise();

	StationMiseDTO selectStationMiseById(String stationName);

	Integer insertStationMise(@Param("mydto") StationMiseDTO smDTO);

	Integer updateStationMise(StationMiseDTO smDTO, String stationName);

	Integer deleteStationMise(String stationName);

}

[Mapper.xml]

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.ayoteralab.main.mapper.UserMapper">

<select id="selectUser" resultType="com.example.ayoteralab.main.dto.UserDTO">
<![CDATA[
	SELECT 
		*
	FROM USER
]]>
</select>

<select id="selectStationMise" resultType="com.example.ayoteralab.main.dto.StationMiseDTO">
<![CDATA[
	SELECT 
		STATION_NAME,
  		NO2_VALUE,
  		O3_VALUE,
  		PM10_VALUE,
  		PM25_VALUE,
  		DATE_TIME
	FROM STATION_MISE
]]>
</select>

<select id="selectStationMiseById" resultType="com.example.ayoteralab.main.dto.StationMiseDTO">
<![CDATA[
	SELECT 
		STATION_NAME,
  		NO2_VALUE,
  		O3_VALUE,
  		PM10_VALUE,
  		PM25_VALUE,
  		DATE_TIME
	FROM STATION_MISE
	WHERE STATION_NAME = #{stationName}
]]>
</select>

<insert id="insertStationMise" parameterType="com.example.ayoteralab.main.dto.StationMiseDTO">
<![CDATA[
	INSERT INTO STATION_MISE
		(STATION_NAME, NO2_VALUE, O3_VALUE, PM10_VALUE, PM25_VALUE, DATE_TIME)
	VALUES
		(#{mydto.stationName}, #{mydto.no2Value}, #{mydto.o3Value}, #{mydto.pm10Value}, #{mydto.pm25Value}, #{mydto.dateTime})		
]]>
</insert>

<update id="updateStationMise" parameterType="java.lang.String">
<![CDATA[
	UPDATE STATION_MISE
	SET PM10_VALUE = #{mydto.pm10Value}, PM25_VALUE = #{mydto.pm25Value}
	WHERE STATION_NAME = #{stationName}
]]>
</update>

<delete id="deleteStationMise" parameterType="java.lang.String">
<![CDATA[
	DELETE FROM STATION_MISE
	WHERE STATION_NAME = #{stationName}
]]>
</delete>

</mapper>

 

이 길다긴 코드에서 어떻게 찾을 수 있을까?? 이런건 현장에서 보면... 1/10도 안되는 참으로 짧은 코드이지요... 우선은 어떤 요청을 했을때 발생했는지 찾습니다.

 

저는 http://localhost:8080/test/stationMise/han river에 method put으로 했을때 발생했기 때문에... Controller에 put으로 되어있는 부분을 찾아봅니다. 이제 service와 mapper를 쭉 따라갑니다. 그렇게 되면 뒤에 2개의 코드가 나오겠죠??

그 중에서 put인 update를 봅니다.... mapper.xml을 보면 이상이 없어보입니다. DTO로 보낸 정보를 잘 원하는 위치에 배치했고...

 

그럼 mapper.java를 봅니다. 이상한 점이 보이시나요??

 

mapper.xml에서는 #{mydto.pm10Value} 처럼... DTO에 @Param으로 alias해서 해당 이름을 사용해서 parameter정보는 대입하였습니다. 하지만... mapper.java에서는 해당 DTO에 대해서 @Param을 정해주지 않았습니다.

 

따라서...

[AS-IS] Integer updateStationMise(StationMiseDTO smDTO, String stationName);

[To-Be] Integer updateStationMise(@Param("mydto") StationMiseDTO smDTO, String stationName);

 

이렇게 해주면... error가 사라지게됩니다.

 

-Ayotera Lab-

 

 

 

댓글