質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.60%

SpringBootでmapに値を詰めようとするとエラーになる

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 3,028

takahiro00

score 60

 前提・実現したいこと

SpringBootでmapにDBから取得した値を格納したいのですが、
コンパイル時にエラーになります。
DBから値の取得方法はControllerクラスからサービスクラスを呼び出して、DBから値を取得しています。
ご教授いただければと思います。

 発生している問題・エラーメッセージ

java.lang.ClassCastException: java.util.HashMap cannot be cast to java.lang.String

 該当のソースコード

package com.kproject01.controller;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;
import com.kproject01.service.UserEditService;

/**
 * ユーザ編集ページのコントローラー
 * @author takahiro
 *
 */
@Controller
public class UserEditController {    

    @Autowired
    UserEditService userEditService;

    /**
     * 初期表示
     * @param mav
     * @return mav
     */
    @GetMapping(path = "/user-edit")
    public ModelAndView useEdit(ModelAndView mav) {
        //userEditService.userEditUserSelect();
        Map<Integer, String> getSelectedUser =
                Collections.unmodifiableMap(new LinkedHashMap<Integer, String>() {
                    private static final long serialVersionUID = 1L;
                    Map<Integer, String> userList = userEditService.userEditUserSelect();
                    {
                        for(Map.Entry<Integer, String>entry :userList.entrySet()){
                            System.out.println(entry.getKey());
                            System.out.println(entry.getValue());
                            put(entry.getKey(), entry.getValue());
                        }
                    }
                });
        mav.setViewName("user-edit");
        return mav;
    }
}
<?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.kproject01.mapper.UserEditMapper">
    <select id="userEditUserSelect" resultType="map">
    select
        user_id,
        first_nm
    from
        m_user
    where
        delete_flg = 0
    </select>
</mapper>
package com.kproject01.mapper;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.annotations.MapKey;

import com.kproject01.entity.UserEditUserSelect;
import com.kproject01.entity.UserTop;

/**
 * ユーザ編集ページ
 * @author takahiro
 *
 */
public interface UserEditMapper {

    //コンボボックスに格納するユーザID、ユーザ名を取得
    @MapKey("userId")
    Map<Integer, String> userEditUserSelect();
}

 補足情報(FW/ツールのバージョンなど)

xmlのresultTypeをhashmapにしたりエンティティにしたりしたのですが、うまくいかず
型が違うというのはなんとなく分かったのですが。。。。

java8
SpringBoot8

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • asahina1979

    2018/11/27 07:54

    一応、 MyBatis / iBatis な Spring boot じゃない

    キャンセル

  • asahina1979

    2018/11/27 07:57

    あと Spring Boot のバージョン8なんてこの世界に使ったことがある人なんていないと思うが

    キャンセル

  • takahiro00

    2018/11/27 19:43

    間違えたSpringBoot2でした

    キャンセル

回答 4

checkベストアンサー

+1

Mybatisの

<select id="userEditUserSelect" resultType="map">

で指定した内容で、@MapKey を使った場合、アノテーションの属性に指定した項目をキーとしたMapにresultTypeで指定した型で、検索結果が格納されます。(mapはjava.util.HashMapのエイリアス)
つまり、userIdが数値型であれば、Map<Integer, Map<String, Object>> で受け取れます。

関連ドキュメントは以下を参考に。

http://www.mybatis.org/mybatis-3/ja/getting-started.html

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/27 19:52

    返信ありがとうございます。
    そうなんですねMap<Integer, Map<String, Object>> の形式になってしまうのですね・・・

    キャンセル

  • 2018/11/27 23:47

    検索結果は何らかのクラス(ValueObject)に詰めることも可能です。@MapKeyのいいところは、検索結果をMapに詰め込むことで、キーに指定した内容を取り出しやすいところにあります。

    キャンセル

0

java.lang.ClassCastException: java.util.HashMap cannot be cast to java.lang.String


文言通り、HashMapをStringにキャストしようとして失敗しているようです。
しかしコード上でそのようなキャストを明示的に行っているところがないので、
怪しいのはuserEditService.userEditUserSelect()で取ってきてるMapが
実はMap<Integer, HashMap<?, ?>>なのではないかということ。

 ちなみに

わざわざforて回さなくても、コンストラクタにMapを渡すだけで(デバッグ用の出力を除き)Mapのコピーを作れます。

        Map<Integer, Map<String, Object>> getSelectedUser =
                Collections.unmodifiableMap(new LinkedHashMap<Integer, Map<String, Object>>(userEditService.userEditUserSelect());

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/27 19:53

    返信ありがとうございます。
    そうなんですねMap<Integer, Map<String, Object>> の形式になってしまうのですね・・・

    キャンセル

0

つMap<Integer, Map<String, Object>> userList = userEditService.userEditUserSelect();

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/27 06:40

    勘違いしていたので訂正。Valueの方にはSelect結果が詰め込まれるはず。

    キャンセル

  • 2018/11/27 19:53

    返信ありがとうございます。
    そうなんですねMap<Integer, Map<String, Object>> の形式になってしまうのですね・・・

    キャンセル

0

解決しました。
直接Map型にするのを諦めてList型にしてから、Map型に変換する方法で解決しました
Controllerは以下のような感じです。

    @GetMapping(path = "/user-edit")
    public ModelAndView useEdit(ModelAndView mav) {
        //userEditService.userEditUserSelect();
        Map<Integer, String> getSelectedUser =
                Collections.unmodifiableMap(new LinkedHashMap<Integer, String>() {
                    private static final long serialVersionUID = 1L;
                    List<UserEditUserSelect> userList = userEditService.userEditUserSelect();
                    {
                        for(int i = 0; i < userList.size(); i++){
                            int userId = userList.get(i).getUserId();
                            String firstNm = userList.get(i).getFirstNm();
                            put(userId, firstNm);
                        }
                    }
                });
        mav.addObject("getSelectedUser", getSelectedUser);
        mav.setViewName("user-edit");
        return mav;
    }

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.60%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る