2016-03-18 11 views
2

Um dieses Problem zu lösen, habe ich eine Menge meines Codes reduziert.MyBatis TooManyResultsException für scheinbar korrektes Mapping

ich weiterhin diesen Fehler bekommen, da ich verschiedene Dinge versuchen, diese Sammlung zum Laufen zu bringen:

verschachtelte Ausnahme ist org.apache.ibatis.exceptions.TooManyResultsException: Erwartet ein Ergebnis (oder null) zu zurück durch selectOne(), aber gefunden: 2

relevante Objekte sind wie folgt:

class Recipe { 
    String name 
    List<RecipeIngredient> ingredients 
} 
class RecipeIngredient { 
    Double measurementAmount 
} 

Ich habe eine Schnittstelle mit meinem Methodenaufruf:

public interface CookbookDao { 
    public Recipe getRecipe(@Param("id")int id) 
} 

Und mein Ergebnis 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> 

Die Abfrage die folgenden Ergebnisse (Hinweis zurück: Während der obige Code hat nur „measurement_amount“ Ich habe enthalten, was der eigentliche sieht End-Ergebnis Satz wie Show helfen, warum ich will/muß diese 2 Zeilen zurück) erhalten:

name | measurement_amount | name | abbreviation | name 
------+--------------------+------+--------------+------- 
Rice |     1 | cup |    | rice 
Rice |     2 | cups |    | water 

ich die Mapper arbeiten, wenn ich die Sammlung o nehmen bekommen ut. Ich habe versucht mit JavaType und ich habe versucht, den zusammengesetzten Schlüssel in der Sammlung, aber es hat immer noch nicht funktioniert. Ich habe Ideen ausprobiert und eine ganze Reihe von Hilfe-Posts angeschaut, aber nichts ist herausgekommen.

ich mit Spring-Boot mit UTD-Versionen von Mybatis und Mybatis-Feder

+0

Ihre Objektkarte sieht so aus, als ob sie versucht, mehrere Datensätze in ein einzelnes Objekt einzufügen. Entweder muss die Klasse resultMap in ein Objekt mit einer Auflistung geändert werden, oder die Abfrage muss ein einzelnes Ergebnis zurückgeben. Ist die Tabelle, die Sie mit mehreren Rice haben, was Sie als Ergebnis erwarten? –

+0

@TahTatsumoto Ich habe die Ergebnisse in meiner ursprünglichen Frage aktualisiert, um zu zeigen, warum es zwei Zeilen gibt. Stellen Sie sich ein Rezept im wirklichen Leben vor - es gibt mehrere Zutaten. Daher gibt die relationale Tabelle mehrere Zeilen von RecipeIngredient für jedes abgefragte Rezept zurück. Das Rezeptobjekt, das ich _does_ zugeordnet habe, hat einen List-Typ, also sollte es - vermutlich - die Sammlung dort abbilden, soweit ich verstanden habe, dass verschachtelte Sammlungen funktionieren. –

+0

Nicht sicher, aber wie sollte MyBatis erkennen, dass beide Zeilen ** ein ** Rezept mit zwei Zutaten und nicht ** zwei ** Rezepte mit jeweils einer Zutat sind?Als erstes würde ich versuchen, den Namen als ID zu setzen anstatt einfach '': '' um ihm zumindest eine Chance zu geben. –

Antwort

2

Es stellt sich heraus, dass Mybatis meine Assoziationen mit aliased Tabellen nicht versteht, so änderte ich meine Abfrage:

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} 

und aktualisiert, um den Mapper den Alias ​​für die Spalte (Rezeptname statt ri.name, usw.), als solche zu verwenden:

<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> 

und es funktioniert!

Dank denen, die

zu helfen
+0

Wie würden Sie Anmerkungen verwenden? – Coder17

0

kommentiert Sie List Verwendung versuchen.

public interface CookbookDao { 
    public List<Recipe> getRecipe(@Param("id")int id); 
} 
Verwandte Themen