terfation 2022-04-08 20:36 采纳率: 0%
浏览 284

MyBatis报Executor was closed这个错误

最近才学mybatis
创建了两张表,一张activity表,一张user表
我想接受前端的loginAct和其他数据,通过loginAct在user表中查找userId,再将id和其他的数据保存在activity表中,可是在查找user时一直报错
这是相关类

//这是dao和service的实现类
public interface UserDao {
    User login(@Param("loginAct") String loginAct,
               @Param("loginPwd") String loginPwd);
    List<User> getUserList();
    User findByLoginAct(String loginAct);
}

public class UserServiceImpl implements UserService {
    private UserDao userDao = SqlSessionUtil.getSession().getMapper(UserDao.class);
    @Override
    public User login(String loginAct, String loginPwd, String ip) throws LoginException {
        User user = userDao.login(loginAct, loginPwd);
        if (user == null){
            throw new LoginException("用户名或密码错误");
        }
        if (user.getExpireTime().compareTo(DataUtil.getSystimestamp()) < 0){
            throw new LoginException("时间已失效");
        }
        if (!"1".equals(user.getLockState())){
            throw new LoginException("已锁定");
        }
        if (!ip.equals(user.getAllowIps())){
            throw new LoginException("非合法ip");
        }
        return user;
    }

    @Override
    public List<User> getUserList() {
        return userDao.getUserList();
    }

    @Override
    public User findByLoginAct(String loginAct) {
        return userDao.findByLoginAct(loginAct);
    }
}

public interface ActivityDao {
    int save(Activity activity);

    List<Activity> getActiveTable(Activity activity);
}

public class ActivityServiceImpl implements ActivityService {
    private final ActivityDao activityDao = (ActivityDao) SqlSessionUtil.getSession().getMapper(ActivityDao.class);
    @Override
    public boolean save(Activity activity){
        boolean flag = true;
        int count = activityDao.save(activity);
        if (count != 1) {flag = false;}
        return flag;
    }

    @Override
    public List<Activity> getActiveTable(Activity activity, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        return activityDao.getActiveTable(activity);
    }
}
//这里下面是工具类
public class SqlSessionUtil {
    private SqlSessionUtil() {}
    private static SqlSessionFactory sqlSessionFactory = null;
    private static ThreadLocal<SqlSession> t = new ThreadLocal<>();
    static {
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static SqlSession getSession(){
        SqlSession session = t.get();
        if (session == null) {
            session = sqlSessionFactory.openSession();
            t.set(session);
        }
        return session;
    }
    public static void close(SqlSession session){
        session.close();
        t.remove();
    }
}

public class Handler implements InvocationHandler {
    Object target = null;
    public Handler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        SqlSession session = null;
        Object obj = null;
        try {
            session = SqlSessionUtil.getSession();
            obj = method.invoke(target, args);
            session.commit();
        } catch (Exception e) {
            if (session != null) {
                session.rollback();
            }
            e.printStackTrace();
            throw e.getCause();
        } finally {
            SqlSessionUtil.close(session);
        }
        return obj;
    }

    public Object getProxy(){
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(), this);
    }
}
public class ServiceFactory {
    public static Object getService(Object service){
        return new Handler(service).getProxy();
    }
}

这是我的mapper.xml

<mapper namespace="com.terfation.crm.settings.dao.UserDao">
    <select id="login" resultType="User">
        select *
        from tbl_user
        where loginAct=#{loginAct} and loginPwd = #{loginPwd}
    </select>
    <select id="getUserList" resultType="User">
        select *
        from tbl_user
    </select>
    <select id="findByLoginAct" resultType="User">
        select *
        from tbl_user
        where loginAct = #{loginAct}
    </select>
</mapper>
<mapper namespace="com.terfation.crm.workbench.dao.ActivityDao">
    <insert id="save">
        insert
        into tbl_activity (
            id, owner, name, startDate, endDate, cost, description, createTime, createBy)
        values (
            #{id},
            #{owner},
            #{name},
            #{startDate},
            #{endDate},
            #{cost},
            #{description},
            #{createTime},
            #{createBy})
    </insert>
</mapper>

这是测试代码

    @org.junit.Test
    public void test1(){
        UserService userService = (UserService) ServiceFactory.getService(new UserServiceImpl());
        ActivityService activityService = (ActivityService) ServiceFactory.getService(new ActivityServiceImpl());
        
        User user = userService.findByLoginAct("root");
        
        Activity activity = new Activity();
        activity.setId("123");
        activity.setName("123");
        activityService.save(activity);//这里报错
    }
    @org.junit.Test
    public void test(){
        UserService userService = (UserService) ServiceFactory.getService(new UserServiceImpl());
        ActivityService activityService = (ActivityService) ServiceFactory.getService(new ActivityServiceImpl());
        Activity activity = new Activity();
        activity.setId("123");
        activity.setName("123");
        activityService.save(activity);
        User user = userService.findByLoginAct("root");//调换位置后这里报错
    }
     //单独运行两个都没有问题
     //单独调试findByLoginAct又出现错误
    @org.junit.Test
    public void tryFind(){
        UserService userService = (UserService) ServiceFactory.getService(new UserServiceImpl());
        User user = userService.findByLoginAct("root");
        System.out.println(user.getId());
    }

    @org.junit.Test
    public void trySave(){
        ActivityService activityService = (ActivityService) ServiceFactory.getService(new ActivityServiceImpl());
        Activity activity = new Activity();
        activity.setId("123");
        activity.setName("123");
        activityService.save(activity);
    }

这是两个调换前的错误信息

img

img

这是两个调换后的错误信息

img

img

  • 写回答

3条回答 默认 最新

  • terfation 2022-04-09 14:43
    关注

    错误原因:
    在第一次创建SQL session查询时进入了代理类的的invoke方法中

            try {
                session = SqlSessionUtil.getSession();
                obj = method.invoke(target, args);
                session.commit();
            } catch (Exception e) {
                if (session != null) {
                    session.rollback();
                }
                e.printStackTrace();
                throw e.getCause();
            } finally {
                SqlSessionUtil.close(session);
            }
    

    此时提交后进入finally中调用工具类将sqlsession关闭了
    在下一次执行操作时还是调用的原来的sqlsession创建的dao对象中的方法

        private final ActivityDao activityDao = (ActivityDao) SqlSessionUtil.getSession().getMapper(ActivityDao.class);
    

    虽然代理类对象调用工具类方法重新获取了到了一个新的sqlsession,但是原来创建dao对象的sqlsession已经关闭了

    关于原本没问题的代码,调试时报错,好像是因为idea debug展现变量 会调用变量的toString方法才产生问题,原因不清除,日后再找错

    评论

报告相同问题?

问题事件

  • 创建了问题 4月8日

悬赏问题

  • ¥300 youchang求解答
  • ¥20 抖音商城拉码器安卓报错求解决办法或者有新的拉码脚本也可以介绍一下
  • ¥15 MPLAB IDE V2.35 报错make[2]: *** [build/default/production/_ext/1472/MSSP_I2C.p1] Error 1
  • ¥15 Unity2D URP项目TextMeshPro(3D)无法显示文字
  • ¥15 新唐M451 DTMF检测和发送代码修改
  • ¥15 在国外文献网站里点击view pdf 加载异常缓慢甚至加载不出来。
  • ¥65 python批量提取发票的信息
  • ¥15 虚幻五引擎内容如何上传至网盘?
  • ¥15 使用mmpose库时出现了问题
  • ¥15 IRI2016模型matlab运行报错