V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
Essaim
V2EX  ›  问与答

Mybatis 在映射 Collection 时会错误的调用 Integer 的构造方法,大家有遇到过么?

  •  2
     
  •   Essaim · 2019-10-14 18:31:02 +08:00 · 1643 次点击
    这是一个创建于 1874 天前的主题,其中的信息可能已经有所发展或是发生改变。

    实体类:

    App.class:
    //App 中有图片列表
    {
       ···
        List<AppImg> imgUrls;
       ···
    }
    AppImg.class:
    
    @AllArgsConstructor
    @NoArgsConstructor
    @TableName("appimgs")
    @Data
    public class AppImgs implements Serializable {
        private static final long serialVersionUID = 1L;
    
        Integer id;
        String imgUrl;
        Integer appId;
    
        public AppImgs(int id,String imgUrl) {
            this.id = id;
            this.imgUrl = imgUrl;
        }
    
    }
    

    mybatis 接口以及映射:

      <!-- 接口 -->
      <select id="getOne" resultMap="appDetail"  >
              SELECT * FROM app  WHERE id = #{appId}
      </select>
    
      <!-- 映射 -->
        <resultMap id="appDetail" type="com.flyaudio.server.iov.appstore.domain.AppDetail">
            <id property="id" column="id" javaType="java.lang.Integer"/>
            <result property="apkSize" column="apk_size" javaType="java.lang.Long"/>
            <result property="bucketName" column="bucket_name" javaType="java.lang.String"/>
            <result property="classifyId" column="classify_id" javaType="java.lang.Integer"/>
            <result property="developer" column="developer" javaType="java.lang.String"/>
            <result property="downloadUrl" column="download_url" javaType="java.lang.String"/>
            <result property="md5" column="md5" javaType="java.lang.String"/>
            <result property="score" column="score" javaType="java.lang.Integer"/>
            <result property="introduce" column="introduce" javaType="java.lang.String"/>
            <result property="name" column="name" javaType="java.lang.String"/>
            <result property="logoUrl" column="logo_url" javaType="java.lang.String"/>
            <result property="packageName" column="package_name" javaType="java.lang.String"/>
            <result property="releaseDate" column="release_date"/>
            <result property="updateLog" column="update_log" javaType="java.lang.String"/>
            <result property="version" column="version" javaType="java.lang.String"/>
            <collection property="imgUrls"
                        ofType="com.flyaudio.server.iov.appstore.domain.AppImg"
                        javaType="list"
                        select="com.flyaudio.server.iov.appstore.mapper.AppimgsMapper.getAppImgsByAppId"
                        column="{appId=id}">
                <id property="id" column="id" javaType="java.lang.Integer"/>
                <result property="imgUrl" column="img_url" javaType="java.lang.String"/>
            </collection>
        </resultMap>
    
    

    collection 对应的 select:

    @Select("SELECT * FEOM appimgs AS a WHERE a.app_id = #{appId}")
    List<AppImg> getAppImgsByAppId(@Param("appId") int appId);
    

    部分 log

    java.lang.NoSuchMethodException: java.lang.Integer.<init>()
    	at java.lang.Class.getConstructor0(Class.java:3082) ~[na:1.8.0_201]
    	at java.lang.Class.getDeclaredConstructor(Class.java:2178) ~[na:1.8.0_201]
    	at org.apache.ibatis.reflection.factory.DefaultObjectFactory.instantiateClass(DefaultObjectFactory.java:63) ~[mybatis-3.5.0.jar:3.5.0]
    	at org.apache.ibatis.reflection.factory.DefaultObjectFactory.create(DefaultObjectFactory.java:51) ~[mybatis-3.5.0.jar:3.5.0]
    	at org.apache.ibatis.reflection.factory.DefaultObjectFactory.create(DefaultObjectFactory.java:43) ~[mybatis-3.5.0.jar:3.5.0]
    	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.instantiateParameterObject(DefaultResultSetHandler.java:805) ~[mybatis-3.5.0.jar:3.5.0]
    	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.prepareCompositeKeyParameter(DefaultResultSetHandler.java:783) ~[mybatis-3.5.0.jar:3.5.0]
    	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.prepareParameterForNestedQuery(DefaultResultSetHandler.java:766) ~[mybatis-3.5.0.jar:3.5.0]
    	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getNestedQueryMappingValue(DefaultResultSetHandler.java:742) ~[mybatis-3.5.0.jar:3.5.0]
    	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getPropertyMappingValue(DefaultResultSetHandler.java:465) ~[mybatis-3.5.0.jar:3.5.0]
    	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.applyPropertyMappings(DefaultResultSetHandler.java:441) ~[mybatis-3.5.0.jar:3.5.0]
    	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getRowValue(DefaultResultSetHandler.java:404) ~[mybatis-3.5.0.jar:3.5.0]
    	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValuesForSimpleResultMap(DefaultResultSetHandler.java:354) ~[mybatis-3.5.0.jar:3.5.0]
    	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValues(DefaultResultSetHandler.java:328) ~[mybatis-3.5.0.jar:3.5.0]
    	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSet(DefaultResultSetHandler.java:301) ~[mybatis-3.5.0.jar:3.5.0]
    	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSets(DefaultResultSetHandler.java:194) ~[mybatis-3.5.0.jar:3.5.0]
    	at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:65) ~[mybatis-3.5.0.jar:3.5.0]
    	at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:79) ~[mybatis-3.5.0.jar:3.5.0]
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_201]
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_201]
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_201]
    	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_201]
    	at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:63) ~[mybatis-3.5.0.jar:3.5.0]
    	at com.sun.proxy.$Proxy296.query(Unknown Source) ~[na:na]
    	at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:63) ~[mybatis-3.5.0.jar:3.5.0]
    	at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:324) ~[mybatis-3.5.0.jar:3.5.0]
    	at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156) ~[mybatis-3.5.0.jar:3.5.0]
    	at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:109) ~[mybatis-3.5.0.jar:3.5.0]
    	at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:83) ~[mybatis-3.5.0.jar:3.5.0]
    	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:148) ~[mybatis-3.5.0.jar:3.5.0]
    	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:141) ~[mybatis-3.5.0.jar:3.5.0]
    	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:77) ~[mybatis-3.5.0.jar:3.5.0]
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_201]
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_201]
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_201]
    	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_201]
    	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:433) ~[mybatis-spring-2.0.0.jar:2.0.0]
    	at com.sun.proxy.$Proxy184.selectOne(Unknown Source) ~[na:na]
    	at org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:166) ~[mybatis-spring-2.0.0.jar:2.0.0]
    	at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:99) ~[mybatis-plus-core-3.1.0.jar:3.1.0]
    	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:61) ~[mybatis-plus-core-3.1.0.jar:3.1.0]
    	at com.sun.proxy.$Proxy188.getOne(Unknown Source) ~[na:na]
    	at com.flyaudio.server.iov.appstore.service.impl.AppServiceImpl.findAppDetailById(AppServiceImpl.java:264) ~[classes/:na]
    
    • 问题

    问题在于 collection 的 select 方法上. 似乎在调用 select 方法的时候传参,会错误的调用new Integer();,但 Integer 是没有无参构造方法的,我对比了另一个能运行的方法,找不出什么问题来.

    • 尝试过的解决方法
    1. 设置各种类型
    2. 把映射方法放到同一个 mapper 中
    3. 各种瞎 jb 跟源码与尝试

    麻烦各位 v 友帮忙看看,有什么不清晰的地方各位海涵了.

    • 这个问题移动到 java 或者 mybatis 是不是会更好?
    4 条回复    2019-10-17 09:43:24 +08:00
    aragakiyuii
        1
    aragakiyuii  
       2019-10-14 19:14:51 +08:00 via Android
    emmm 两个表 join 一下可以嘛,collection 标签里就不写 select 和 javaType 参数了。

    像主楼中这么写 collection 会导致整个查询变慢。。(印象中
    Essaim
        2
    Essaim  
    OP
       2019-10-15 09:23:55 +08:00
    @aragakiyuii 好的,谢谢,其实我比较想搞明白我哪里错了,或者这是不是 mybatis 3 的一个 bug.
    aragakiyuii
        3
    aragakiyuii  
       2019-10-15 10:46:30 +08:00
    @Essaim emmm collection 标签里的 column 不应该是"{appId=id}"吧
    我自己之前用没写过这样的表达式,这是官网的例子
    Essaim
        4
    Essaim  
    OP
       2019-10-17 09:43:24 +08:00
    @aragakiyuii 确实是 column 的问题,使用官方文档的方法可以使用.
    使用"{appId=id}"的原因一是我没有正确的查阅官方文档,第二个是我在以前的使用中,用这个形式的表达式是可以正常使用的,所以忽略了这个表达式,后面有时间我深究一下这个表达式有什么讲究.
    谢了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2730 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 09:27 · PVG 17:27 · LAX 01:27 · JFK 04:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.