[mybatis] Expected one result (or null) to be returned by selectOne(), but found

2022. 10. 7. 18:47프로그래밍/TroubleShooting

728x90

mybatis 를 사용 할 때, 약간은 생각해 볼만한 문제 인 것 같습니다.

우선 다음과 같이 Mapper를 위한 xml 을 만들었습니다.

 

<mapper>

	<select id="selectSubTeam" parameterType="java.util.Map" resultType="java.util.Map">
		SELECT 
			TEAM_NO, TEAM_NM 
		FROM 
			TEAM 
		WHERE 
			Company=#{Company} AND 
			Team=#{Team}
	</select>
	
	
</mapper>

위와 같이 정의 한다면, 인터페이스에 정의 될 메서드 시그너쳐는 이렇게 될 것입니다.

public List<Map<String,String>> selectSubTeam(Map<String, String> paramMap);


위의 메서드에서 해당 결과를 풀어서 보기 보기 위해서는 아래와 같은 코드를 사용 해야 합니다.

Map<String, String> paramMap = new HashMap<String,String>();
paramMap.put("Company", Company);
paramMap.put("Team", Team);

List<Map<String,String>> teamList = myMapper.selectSubTeam(paramMap);
			
for(Map<String,String> teamMap:teamList)
{
	System.out.println("TEAM_NO:" + teamMap.get("TEAM_NO") + "TEAM_NM:" + teamMap.get("TEAM_NM"));
}

그러면, 제목과 같은 오류는 어떻게 생겼을까요?


결론부터 말씀드리자면, 저의 문제는 위 처럼 객체를 풀어쓰지 않고 Map 객체를 하나만 받아서 생긴 문제 였습니다.
어떻게 헷갈렸느냐구요?

List 형식으로 mybatis 측에서 줄 것이라고, 예상하지 않고, 그냥 결과를 Map 객체를 이용해서 담아 줄것이라고 예상 했던 것이었습니다.

즉,

Map<"TEAM_NO", "팀번호1">
Map<"TEAM_NM", "팀이름1">
...
Map<"TEAM_NO", "팀번호n">
Map<"TEAM_NM", "팀이름n">

조금만 생각해 보면 맵에 키 값이 중복이 일어 난다는 사실을 알 수 있었을 텐데요...

 

사실 약간은 불합리해 보이기는 한데요,

왜냐하면 리스트에다 다시 맵을 담아서 주는 것이 메모리 상 문제도 그렇고 성능 상으로도 그렇게 좋아보이는 선택은 아닌 듯 합니다.

그리고 이것 보다 더 좋은 방안을 mybatis에서 내 놓았는 데, 제가 찾아 보질 못해서 그럴수도 있을 것 같습니다.

 

여하튼, 아래처럼 List<String[]> 이렇게 선언해 주면 되지 않을까? 하는 생각이 들어서 였습니다 만,

<mapper>

	<select id="selectSubTeam" parameterType="java.util.Map" resultType="String[]">
		SELECT 
			TEAM_NO, TEAM_NM 
		FROM 
			TEAM 
		WHERE 
			Company=#{Company} AND 
			Team=#{Team}
	</select>
	
	
</mapper>

resultType을 다음과 같이 받을 수 받을 수만 있다면, 

resultType="String[]"

그냥 TEAM_NO, TEAM_NM 두개의 쌍으로 받아서 처리하면 어떨까 하는 어리석은 생각만 해 보았습니다.

 

사실, 여기서는 TEAM_NO, TEAM_NM 두개의 컬럼의 결과만 받을려고 했을 때만 한정되는 것이라

여러가지 상황을 고려해 보면(숫자, CLOB, BLOB 날짜 등등), 위와 같은 선언은 못한다는 것을 정확히 알았을 텐데 말이죠


728x90