mybatis双向多对一 报java.lang.StackOverflowError

java.lang.StackOverflowError
    at java.base/java.lang.ClassLoader.defineClass1(Native Method)
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
    at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
    at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:801)
    at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:699)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:622)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:580)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    at org.apache.ibatis.executor.loader.javassist.JavassistProxyFactory$EnhancedResultObjectProxyImpl.invoke(JavassistProxyFactory.java:163)
    at com.nwl.entity.User_$$_jvst8cb_1.toString(User_$$_jvst8cb_1.java)
    at java.base/java.lang.String.valueOf(String.java:2951)
    at com.nwl.entity.Pet.toString(Pet.java:43)
    at com.nwl.entity.Pet_$$_jvst8cb_0._d13toString(Pet_$$_jvst8cb_0.java)
    at jdk.internal.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.apache.ibatis.executor.loader.javassist.JavassistProxyFactory$EnhancedResultObjectProxyImpl.invoke(JavassistProxyFactory.java:161)
    at com.nwl.entity.Pet_$$_jvst8cb_0.toString(Pet_$$_jvst8cb_0.java)
    at java.base/java.lang.String.valueOf(String.java:2951)
    at java.base/java.lang.StringBuilder.append(StringBuilder.java:168)
    at java.base/java.util.AbstractCollection.toString(AbstractCollection.java:473)
    at java.base/java.lang.String.valueOf(String.java:2951)
    at com.nwl.entity.User.toString(User.java:45)

 

代码如下:

public class Pet {
    private Integer id;
    private String nickname;
    private User user;

    public Pet() {
    }

    public Pet(Integer id, String nickname, User user) {
        this.id = id;
        this.nickname = nickname;
        this.user = user;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Override
    public String toString() {
        return "Pet{" +
                "id=" + id +
                ", nickname='" + nickname + '\'' +
                ", user=" + user +
                '}';
    }
}

public class User {
    private Integer id;
    private String name;
    private List<Pet> pets;

    public User() {
    }

    public User(Integer id, String name, List<Pet> pets) {
        this.id = id;
        this.name = name;
        this.pets = pets;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Pet> getPets() {
        return pets;
    }

    public void setPets(List<Pet> pets) {
        this.pets = pets;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", pets=" + pets +
                '}';
    }
}

public interface PetMapper {
    List<Pet> queryByUserId(Integer userId);
    Pet queryById(Integer id);
}

PetMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.nwl.mapper.PetMapper">
    <resultMap id="PetResultMap" type="Pet">
        <id property="id" column="id"/>
        <result property="nickname" column="nickname"/>
        <association property="user" column="user_id" select="com.nwl.mapper.UserMapper.queryById"/>
    </resultMap>
    <select id="queryById" parameterType="integer" resultMap="PetResultMap">
        select * from mybatis_pet where id=#{id}
    </select>

    <select id="queryByUserId" parameterType="integer" resultMap="PetResultMap">
        select * from mybatis_pet where user_id=#{userId}
    </select>
</mapper>

public interface UserMapper {
    User queryById(Integer id);
}

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.nwl.mapper.UserMapper">
    <resultMap id="userResultMap" type="User">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
<!--     <collection>表示这个映射是一个集合属性
         ofType="Pet"表示这个集合是Pet类型的
         column="id"表示 select * from mybatis_user from id=#{id}的id
         select="com.nwl.mapper.PetMapper.queryByUserId"表示调用此方法返回该用户的所有pet-->
        <collection property="pets" ofType="Pet" column="id"
                    select="com.nwl.mapper.PetMapper.queryByUserId"/>
    </resultMap>
    <select id="queryById" parameterType="Integer" resultMap="userResultMap">
        select * from mybatis_user where id=#{id}
    </select>
</mapper>

@Test
    public void test4(){
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        System.out.println(mapper.queryById(1));
    }

    @Test
    public void test5(){
        PetMapper mapper = sqlSession.getMapper(PetMapper.class);
        System.out.println(mapper.queryById(1));
    }

 

原因是Pet类的toString方法有User对象,User类的toString方法有Pet对象,如果直接使用toString方法输出对象会形成死循环,所以会报这个错,要想不报错可以单独输出对象的属性

 

@Test
    public void test4(){
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.queryById(1);
        System.out.println(user.getName()+"的宠物有:");
        for (Pet pet:user.getPets()){
            System.out.println(pet.getNickname());
        }
    }
    @Test
    public void test5(){
        PetMapper mapper = sqlSession.getMapper(PetMapper.class);
        Pet pet = mapper.queryById(1);
        System.out.println(pet.getNickname()+":"+pet.getUser().getName());
    }

 

 

 

posted @ 2021-11-05 11:42  0牛牛牛  阅读(437)  评论(0)    收藏  举报