mybatis-mapper / mapper

MyBatis Mapper
https://mapper.mybatis.io
Apache License 2.0
325 stars 47 forks source link

达梦:No setter found for the keyProperty 'id' in '实体类' #84

Closed Ryoui closed 11 months ago

Ryoui commented 11 months ago

达梦数据,使用mapper.insertSelective(xx);是报错,经测试使用mybatis-plus+达梦是不会报错的,在io.mapper+mysql也不会报错。 实体类主键是:u_id。,虽然报错,但数据是插入了数据库的,以下是错误信息:

org.apache.ibatis.executor.ExecutorException: No setter found for the keyProperty 'id' in 'xxx.BugTest'.
    at org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator$KeyAssigner.assign(Jdbc3KeyGenerator.java:261)
    at org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator.lambda$assignKeysToParam$0(Jdbc3KeyGenerator.java:124)
    at java.util.ArrayList.forEach(ArrayList.java:1257)
    at org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator.assignKeysToParam(Jdbc3KeyGenerator.java:124)
    at org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator.assignKeys(Jdbc3KeyGenerator.java:104)
    at org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator.processBatch(Jdbc3KeyGenerator.java:85)
    at org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator.processAfter(Jdbc3KeyGenerator.java:71)
    at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:52)
    at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:75)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61)
    at com.sun.proxy.$Proxy251.update(Unknown Source)
    at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:50)
    at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117)
    at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61)
    at com.sun.proxy.$Proxy248.update(Unknown Source)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:197)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:184)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:427)
    at com.sun.proxy.$Proxy155.insert(Unknown Source)
    at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:272)
    at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:62)
    at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:142)
    at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86)
    at com.sun.proxy.$Proxy185.insertSelective(Unknown Source)

实体类:

@Entity.Table(value = "bug_test", remark = "bug复现类")
public class BugTest implements Serializable {
    private static final long serialVersionUID = -3906291302100871629L;
    @Entity.Column(value = "u_id", id = true)
    private Long uId;

    private String userName;

    public Long getuId() {
        return uId;
    }

    public void setuId(Long uId) {
        this.uId = uId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }
}

mapper:

@org.apache.ibatis.annotations.Mapper
public interface BugTestMapper extends Mapper<BugTest,Long> {

}

xml:

<mapper namespace="xxx.BugTestMapper">
  <resultMap id="BaseResultMap" type="xx.BugTest">
    <id column="u_id" jdbcType="BIGINT" property="uId" />
    <result column="user_name" jdbcType="VARCHAR" property="userName" />
  </resultMap>
  <sql id="Base_Column_List">
    u_id, user_name
  </sql>

</mapper>
abel533 commented 11 months ago

问题在 insertSelective 接口:

  @Override
  @Lang(Caching.class)
  //@SelectKey(statement = "SELECT SEQ.NEXTVAL FROM DUAL", keyProperty = "id", before = true, resultType = long.class)
  @Options(useGeneratedKeys = true, keyProperty = "id")
  @InsertProvider(type = EntityProvider.class, method = "insertSelective")
  int insertSelective(T entity);

这里指定的 @Options(useGeneratedKeys = true, keyProperty = "id"),如果你用的是最新2.x版本,建议使用:

@Mapper
public interface BugTestMapper extends BaseMapper<BugTest,Long> {

}

并在实体类指定:

@Entity.Table(value = "bug_test", remark = "bug复现类")
public class BugTest implements Serializable {
    private static final long serialVersionUID = -3906291302100871629L;
    @Entity.Column(value = "u_id", id = true, useGeneratedKeys = true)
    private Long uId;

最新版本中使用 useGeneratedKeys = true 时会自动根据当前字段设置 keyProperty

如果用的不是最新版本,可以如下改动:

@org.apache.ibatis.annotations.Mapper
public interface BugTestMapper extends Mapper<BugTest,Long> {
  @Override
  @Lang(Caching.class)
  @Options(useGeneratedKeys = true, keyProperty = "uId")
  @InsertProvider(type = EntityProvider.class, method = "insertSelective")
  int insertSelective(BugTest entity);
}
abel533 commented 11 months ago

可以加Q群交流:277256950

Ryoui commented 11 months ago

感谢,已解决。我是2.x,直接改用baseMapper即可,实体类没添加useGeneratedkeys,验证成功。