For the sake of resolving this problem I have pared down a lot of my code.
I continue to get this error as I try different things to get this collection working:
nested exception is org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 2
Relevant objects are as follows:
class Recipe {
String name
List<RecipeIngredient> ingredients
}
class RecipeIngredient {
Double measurementAmount
}
I have an interface with my method call:
public interface CookbookDao {
public Recipe getRecipe(@Param("id")int id)
}
And my result mapper:
<?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="cookbook.daos.CookbookDao">
<select id="getRecipe" resultMap="Recipe">
SELECT
r.name,
ri.measurement_amount
FROM
recipe r
INNER JOIN recipe_ingredient ri on ri.recipe_id = r.id
WHERE
r.id = #{id}
</select>
<resultMap id="Recipe" type="cookbook.domain.Recipe">
<result property="name" column="r.name" />
<collection property="ingredients" ofType="cookbook.domain.RecipeIngredient">
<result property="measurementAmount" column="ri.measurement_amount"/>
</collection>
</resultMap>
</mapper>
The query returns the following results (Note: While the above code only has "measurement_amount" I've included what the actual, end-result set looks like to help show why I want/need to get these 2 rows back):
name | measurement_amount | name | abbreviation | name
------+--------------------+------+--------------+-------
Rice | 1 | cup | | rice
Rice | 2 | cups | | water
I can get the mapper to work when I take the collection out. I have tried using javaType and I have tried using the composite key in the collection, but it still didn't work. I have run out ideas and have looked in a ton of help posts but nothing stood out.
I'm using Spring Boot with UTD versions of mybatis and mybatis-spring
It turns out that MyBatis doesn't understand my associations with aliased tables, so I changed my query to:
SELECT
r.name as recipe_name,
ri.measurement_amount as measurement_amount
FROM
recipe r
INNER JOIN recipe_ingredient ri on ri.recipe_id = r.id
WHERE
r.id = #{id}
and updated the mapper to use the alias for column (recipe_name instead of ri.name, etc), as such:
<resultMap id="Recipe" type="cookbook.domain.Recipe">
<result property="name" column="recipe_name" />
<collection property="ingredients" ofType="cookbook.domain.RecipeIngredient">
<result property="measurementAmount" column="measurement_amount"/>
</collection>
</resultMap>
and it worked!
Thanks to those who commented to help