You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MyBatis中使用Guava不可变集合?

解决MyBatis返回Guava ImmutableList的实例化异常问题

问题原因

MyBatis默认的DefaultObjectFactory通过反射实例化集合类,但ImmutableList是抽象类,没有公开的无参构造器,无法通过直接反射创建实例,因此抛出InstantiationException。


解决方案

方案1:转成标准集合后再包装(最简单直接)

修改Mapper接口返回Java标准List,在业务层调用Guava的静态方法转成ImmutableList:

修改后的Mapper接口:

@Mapper
public interface UtilityRepository {
  List<Integer> getAllIds();
}

业务层转换:

@ApplicationScoped
@AllArgsConstructor
public class UtilityService {
  private final UtilityRepository repository;
  
  public ImmutableList<Integer> getAllIds() {
    return ImmutableList.copyOf(repository.getAllIds());
  }
}

这种方式无需修改MyBatis配置,代码侵入性低,适合大多数场景。

方案2:自定义ObjectFactory支持Guava不可变集合

如果项目中大量使用Guava不可变集合,可以自定义MyBatis的ObjectFactory,让它自动处理ImmutableList等类型的实例化:

自定义GuavaObjectFactory:

import com.google.common.collect.ImmutableList;
import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
import java.util.Collection;
import java.util.List;

public class GuavaObjectFactory extends DefaultObjectFactory {
  @Override
  public <T> T create(Class<T> type) {
    // 处理空集合的情况
    if (ImmutableList.class.isAssignableFrom(type)) {
      return type.cast(ImmutableList.of());
    }
    return super.create(type);
  }

  @Override
  public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
    // 处理已有集合转ImmutableList的情况
    if (ImmutableList.class.isAssignableFrom(type) 
        && constructorArgs.size() == 1 
        && constructorArgs.get(0) instanceof Collection) {
      return type.cast(ImmutableList.copyOf((Collection<?>) constructorArgs.get(0)));
    }
    return super.create(type, constructorArgTypes, constructorArgs);
  }
}

配置MyBatis使用自定义ObjectFactory:

  • 如果是XML配置文件:
<configuration>
  <objectFactory type="com.yourpackage.GuavaObjectFactory"/>
</configuration>
  • 如果是Spring Boot/Quarkus等配置文件(以application.properties为例):
mybatis.configuration.object-factory=com.yourpackage.GuavaObjectFactory

配置完成后,Mapper接口可以直接返回ImmutableList<Integer>,无需额外转换。


内容的提问来源于stack exchange,提问作者acanthite

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 17:09:56