1

I only defined a parameterized construction method in the class. When the number of parameters and the number of mappings are different, the query can still be correct.

I'm doing a one-to-many association query. When the ArrayList is not written in the constructor, everything works fine.

public class Classes {
private int classId;
private String className;
private ArrayList<Person> people;

public Classes(int classId, String className) {
    this.classId = classId;
    this.className = className;
}

@Override
public String toString() {
    return "classes{" +
            "classId=" + classId +
            ", className='" + className + '\'' +
            ", people=" + people +
            '}';
}}

Mapper.xml

<select id="queryPersonById" resultType="com.cztcode.mybatis.Person">
    select * from person where id=#{id}
</select>

<resultMap id="class_people_map" type="Classes">
    <id property="classId" column="class_id"/>
    <result property="className" column="class_name"/>
    <collection property="people" ofType="Person" >
        <id property="id" column="id"/>
        <result property="age" column="age"/>
        <result property="name" column="name"/>
    </collection>
</resultMap>

Database query results

classes{classId=1, className='A', people=[Person{id=0, name='Shi', age=23, card=null}, Person{id=1, name='Li', age=18, card=null}]}

The result of this query is correct but strange. Because I did not define a parameterless constructor.


But if I write like this:

public class Classes {
private int classId;
private String className;
private ArrayList<Person> people;

public Classes(int classId, String className, ArrayList<Person> people) {
    this.classId = classId;
    this.className = className;
    this.people = people;
}

@Override
public String toString() {
    return "classes{" +
            "classId=" + classId +
            ", className='" + className + '\'' +
            ", people=" + people +
            '}';
}}

I will get an error:

 Exception in thread "main" org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: org.apache.ibatis.reflection.ReflectionException: Error instantiating class com.cztcode.mybatis.Classes with invalid types (int,String,ArrayList) or values (1,A,0). Cause: java.lang.IllegalArgumentException: argument type mismatch
### The error may exist in PersonMapper.xml
### The error may involve com.cztcode.mapper.PersonMapper.queryAllClassAndPeople
### The error occurred while handling results
### SQL: select * from class,person where  class.class_id=person.class and class.class_id=?
### Cause: org.apache.ibatis.reflection.ReflectionException: Error instantiating class com.cztcode.mybatis.Classes with invalid types (int,String,ArrayList) or values (1,A,0). Cause: java.lang.IllegalArgumentException: argument type mismatch

I don't understand why this is happening. If I write a parameterized constructor, it will not automatically provide a parameterless constructor. Mybatis will create an object when mapping, but I don't know how mybatis is created.

If I define a constructor without writing a parameterless constructor, which method is called when mybatis creates the object? If it is a parameterless constructor, I should not report an error when I define a parameterized constructor, but in fact he reports an error and the types do not match.

It is successful to remove the parameter that does not match the type, that is to say, the parameterized constructor is automatically called when the object is created, it is not very clear.

I just learned to use mybatis, I don’t know why this happens

Jellow
  • 93
  • 6
  • 1
    I don't know mybatis. But is looks like the declaration of people is wrong in the Mapper.xml (why not use javaType="java.util.ArrayList). See https://stackoverflow.com/questions/42532187/type-handler-for-arraylist-in-mybatis Also the error message is clear, it is using reflection and trying to pass in 0 as an arrayList and will fail. – Jocke Jul 04 '20 at 10:11
  • 1
    You need to specify `` in the result map. See the [doc](https://mybatis.org/mybatis-3/sqlmap-xml.html#Advanced_Result_Maps) for the details. When there is no ``, MyBatis requires the default (i.e. no-arg) constructor. – ave Jul 04 '20 at 10:28
  • Thank you very much, my question has been solved by your answer. It seems that if no is defined and a parameterized constructor is defined, it will be forcibly assigned to the parameterized parameter in the order of the database. – Jellow Jul 04 '20 at 10:40

0 Answers0