mybatis-mapper / mapper

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

Fn缓存严重BUG,导致内存无限增长! #108

Closed mfeng-ya closed 1 month ago

mfeng-ya commented 1 month ago

Fn内两个缓存map使用Fn实例当作key,FnName对象每次都会创建新实例,且未实现hashCode跟equals方法,导致缓存无限增长! 另外此处缓存是否可考虑限制下大小

abel533 commented 1 month ago

确认是bug,来个PR?

参考: 单元测试,FnTest添加:

  @Test
  public void testMemoryOverflow() throws InterruptedException {
    for (int i = 0; i < 100; i++) {
      System.out.println(((Fn<User, Object>) User::getUserName).toColumn());
      Assert.assertEquals(1, Fn.FN_COLUMN_MAP.size());
      Assert.assertEquals(1, Fn.FN_CLASS_FIELD_MAP.size());
    }
    for (int i = 0; i < 100; i++) {
      System.out.println(Fn.field(User.class, "userName").toColumn());
      Assert.assertEquals(2, Fn.FN_COLUMN_MAP.size());
      Assert.assertEquals(2, Fn.FN_CLASS_FIELD_MAP.size());
    }
  }

Fn.java 修改其中的 FnName,添加下面方法:


    @Override
    public boolean equals(Object o) {
      if (this == o) return true;
      if (o == null || getClass() != o.getClass()) return false;
      FnName<?, ?> fnName = (FnName<?, ?>) o;
      return column == fnName.column && Objects.equals(entityClass, fnName.entityClass) && Objects.equals(name, fnName.name);
    }

    @Override
    public int hashCode() {
      return Objects.hash(entityClass, name, column);
    }
mfeng-ya commented 1 month ago

Fn暴露的方法用到主要是获取column属性,其它方法是否多余,field跟column的映射关系是否可放到EntityTable处理,减少Fn内部实现的复杂性

abel533 commented 1 month ago

方法确实多,所有方法都有用。。这些方法是针对扩展使用的,直接使用通用方法是不需要关注的。