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

2019-10-14 18:31:02 +08:00
 Essaim

实体类:

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 友帮忙看看,有什么不清晰的地方各位海涵了.

1548 次点击
所在节点    问与答
4 条回复
aragakiyuii
2019-10-14 19:14:51 +08:00
emmm 两个表 join 一下可以嘛,collection 标签里就不写 select 和 javaType 参数了。

像主楼中这么写 collection 会导致整个查询变慢。。(印象中
Essaim
2019-10-15 09:23:55 +08:00
@aragakiyuii 好的,谢谢,其实我比较想搞明白我哪里错了,或者这是不是 mybatis 3 的一个 bug.
aragakiyuii
2019-10-15 10:46:30 +08:00
@Essaim emmm collection 标签里的 column 不应该是"{appId=id}"吧
我自己之前用没写过这样的表达式,这是官网的例子
Essaim
2019-10-17 09:43:24 +08:00
@aragakiyuii 确实是 column 的问题,使用官方文档的方法可以使用.
使用"{appId=id}"的原因一是我没有正确的查阅官方文档,第二个是我在以前的使用中,用这个形式的表达式是可以正常使用的,所以忽略了这个表达式,后面有时间我深究一下这个表达式有什么讲究.
谢了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/609255

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX