一个没有创建默认构造函数,引发的mybatis报错。导致No constructor found in com.leo.course.scheduling.domain

探讨了在MyBatis中遇到的ExecutorException错误,详细分析了由于未找到匹配构造函数导致的问题,解释了DefaultResultSetHandler如何处理resultType,以及如何正确地在实体类中定义构造函数以避免此类错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2019-03-06 20:57:51.290 DEBUG 13588 --- [p-nio-81-exec-4] c.l.c.s.m.D.getPageQueryList             : ==>  Preparing: select id,depno,depname,majorno,majorname,addtime,flag from department where id limit ?,? 
2019-03-06 20:57:51.290 DEBUG 13588 --- [p-nio-81-exec-4] c.l.c.s.m.D.getPageQueryList             : ==> Parameters: 0(Integer), 10(Integer)
2019-03-06 20:57:51.294 ERROR 13588 --- [p-nio-81-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.executor.ExecutorException: No constructor found in com.leo.course.scheduling.domain.Department matching [java.lang.Integer, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.sql.Timestamp, java.lang.String]] with root cause

org.apache.ibatis.executor.ExecutorException: No constructor found in com.leo.course.scheduling.domain.Department matching [java.lang.Integer, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.sql.Timestamp, java.lang.String]

有上面打印的信息来说是没有提供默认的构造函数,可是我已经书写了有参的构造函数,看下面的实体类,

package com.leo.course.scheduling.domain;

import java.util.Date;

import org.springframework.format.annotation.DateTimeFormat;

import com.fasterxml.jackson.annotation.JsonFormat;

public class Department {
	private Integer id;
	private String depno;
	private String depname;
	private String majorno;
	private String majorname;
	private String flag;
	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
	@JsonFormat(pattern = "yyyy-MM-dd", timezone="GMT+8")
	private Date addtime;
	/**
	 * @return the id
	 */
	public Integer getId() {
		return id;
	}
	/**
	 * @param id the id to set
	 */
	public void setId(Integer id) {
		this.id = id;
	}
	/**
	 * @return the depno
	 */
	public String getDepno() {
		return depno;
	}
	/**
	 * @param depno the depno to set
	 */
	public void setDepno(String depno) {
		this.depno = depno;
	}
	/**
	 * @return the depname
	 */
	public String getDepname() {
		return depname;
	}
	/**
	 * @param depname the depname to set
	 */
	public void setDepname(String depname) {
		this.depname = depname;
	}
	/**
	 * @return the majorno
	 */
	public String getMajorno() {
		return majorno;
	}
	/**
	 * @param majorno the majorno to set
	 */
	public void setMajorno(String majorno) {
		this.majorno = majorno;
	}
	/**
	 * @return the majorname
	 */
	public String getMajorname() {
		return majorname;
	}
	/**
	 * @param majorname the majorname to set
	 */
	public void setMajorname(String majorname) {
		this.majorname = majorname;
	}
	/**
	 * @return the flag
	 */
	public String getFlag() {
		return flag;
	}
	/**
	 * @param flag the flag to set
	 */
	public void setFlag(String flag) {
		this.flag = flag;
	}
	/**
	 * @return the addtime
	 */
	public Date getAddtime() {
		return addtime;
	}
	/**
	 * @param addtime the addtime to set
	 */
	public void setAddtime(Date addtime) {
		this.addtime = addtime;
	}
	public Department(Integer id, String depno, String depname, String majorno, String majorname, String flag,
			Date addtime) {
		super();
		this.id = id;
		this.depno = depno;
		this.depname = depname;
		this.majorno = majorno;
		this.majorname = majorname;
		this.flag = flag;
		this.addtime = addtime;
	}
	/**
	 * 没有这这个构造函数,为何不能默认加入呢
	 
	public Department() {
		super();
	}
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "Department [id=" + id + ", depno=" + depno + ", depname=" + depname + ", majorno=" + majorno
				+ ", majorname=" + majorname + ", flag=" + flag + ", addtime=" + addtime + "]";
	}
	
	
}

为什么会出现这样的错误呢,原来是xml中返回的是resultType中设定了返回的是这个实体类而这个ResultType是通过DefaultResultSetHandler这个类进行对resultType进行解析的,其中咱们主要看其中的主要代码:

private Object createByConstructorSignature(ResultSetWrapper rsw, Class<?> resultType, List<Class<?>> constructorArgTypes, List<Object> constructorArgs,
                                              String columnPrefix) throws SQLException {
    final Constructor<?>[] constructors = resultType.getDeclaredConstructors();
    final Constructor<?> annotatedConstructor = findAnnotatedConstructor(constructors);
    if (annotatedConstructor != null) {
      return createUsingConstructor(rsw, resultType, constructorArgTypes, constructorArgs, columnPrefix, annotatedConstructor);
    } else {
      for (Constructor<?> constructor : constructors) {
        if (allowedConstructor(constructor, rsw.getClassNames())) {
          return createUsingConstructor(rsw, resultType, constructorArgTypes, constructorArgs, columnPrefix, constructor);
        }
      }
    }
    throw new ExecutorException("No constructor found in " + resultType.getName() + " matching " + rsw.getClassNames());
  }

其中源码中创建构造函数签名这个类中,必须要通过反射获取声明的构造者:
final Constructor<?>[] constructors = resultType.getDeclaredConstructors();

先是要判断是否构造函数为空,不为空的话创建这个构造函数,如果为空,先进行对其进行遍历,如果是允许这个构造函数的者进行使用,如果不符合上面的规则,抛出异常,    throw new ExecutorException("No constructor found in " + resultType.getName() + " matching " + rsw.getClassNames());

使用这个构造函数进行创建是主要使用其构造函数,说明了这里并没有使用new出对象,因为new的时候必定会加入这个默认构造器而这里是通过反射获取的所以不能为其自动加入这个构造器,所以这就是问题的最终原因,只需要把构造器函数给写出来。

在看下反射类中的所获得对象的构造方法

publicConstructor<T> getConstructor(Class<?>... parameterTypes):获取单个构造方法,参数表示的是:你要获取的构造方法的构造参数个数及数据类型的class字节码文件对象

  publicConstructor<T> getDeclaredConstructor(Class<?>... parameterTypes):获取单个构造方法(能获取私有的,但要用Constructor类的setAccessible方法设置访问权限),参数表示的是:你要获取的构造方法的构造参数个数及数据类型的class字节码文件对象
所以条件都不能够满足所以出现异常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kay三石

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值