ejb.jar情况下mybatis没有初始化

mybatis is not initialized in case of ejb.jar

看来我所做的还不完整,我的代码中还缺少一些东西。

我想在 EJB 中使用 MyBatis + mybatis-cdi。我的 jar 仅包含一个无状态 ejb class 和一个会话工厂生产者 class。我认为问题在于我的 MyBatis 会话工厂生产者从未被 EE 容器调用(我在日志文件中看不到“MyBatis SessionFactory is initializing...”日志条目)。

部署时出现以下错误:

WELD-001408: Unsatisfied dependencies for type ConfigurationDao with qualifiers @Default at injection point ....

当我将相同的 classes(EJB + 会话工厂生产者 classes)打包到 war 时,我可以在日志中看到会话工厂生产者被调用。但是我需要将它们打包到一个简单的 ejb 而不是 war,因为我正在构建一个 EJB 服务,它被另一个 wars 使用。

这是我的装配结构:

EAR
  +--- commons.jar (interfaces)
  +--- configuration-service.jar (stateless ejb + mybatis mapper interface + session factory producer)
  +--- restapi-1.war
  +--- restapi-2.war

以下classes 坐在配置-service.jar:

Session Factory 制作人

//@Stateless
public class SessionFactoryProducer {

    private static final Logger LOGGER = ...;

    @ApplicationScoped
    @Produces
    @SessionFactoryProvider
    public SqlSessionFactory produce() throws Exception {
        LOGGER.info("MyBatis SessionFactory is initializing...");

        try (Reader reader = Resources.getResourceAsReader("mybatis.xml")) {
            return new SqlSessionFactoryBuilder().build(reader);
        }
    }
}

无状态 ejb

@Stateless
public class ConfigurationBean implements ConfigurationService {

   @Inject
   private ConfigurationDao configurationDao;

   public void setStringValue(final Configuration configuration) {
      ...
      // save to database
      configurationDao.insert(configuration);
      ...
   }

   public String getStringValue(final String key) {
      return configurationDao.findByKey(key).map(Configuration::getValue).orElse(null);
   }
}

MyBatis 映射器:

@Mapper
public interface ConfigurationDao {

    @Select("SELECT ...")
    Configuration findByKey(@Param("key") String key);

    @Insert("INSERT INTO ...")
    void insert(Configuration configuration);
}

用法来自 war(球衣休息)

@Path("/")
public class MyClass {
    @Inject
    private ConfigurationService configurationService;

    @GET
    @Produces(MediaType.APPLICATION_UTF8_JSON)
    public String doSomething() {
        String something = configurationService.getStringValue(KEY);
        ...
    }
}

对于我的 ear/ejb 应用程序,这是我声明 SessionFactoryProvider 的方式:

@Local(ISqlSessionFactoryProvider.class)
@Stateless
public class SqlSessionFactoryProvider implements ISqlSessionFactoryProvider


@Local
public interface ISqlSessionFactoryProvider {

    SqlSessionFactory produceFactory() throws IOException;

}

然后在 EJB 中,我注入 SqlSession 并从中检索 Mapper。但是直接注入映射器应该按照 documentation.

中指定的方式工作

在我的另一个应用程序:一个简单的网络应用程序中,我声明 SessionFactoryProvider 的方式与您相同。

这可能不是最好的方法,但它确实有效。

我认为存在文件 "empty" beans.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!-- This file can be an empty text file (0 bytes) -->
<!-- We're declaring the schema to save you time if you do have to configure 
  this in the future -->
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="
        http://java.sun.com/xml/ns/javaee 
        http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">

</beans>

在 WEB-INF(对于 webapp)或 META-INF(对于 ejb-jar)目录中可能允许容器服务器active/load一些东西。 我刚刚 checked:它 开启 CDI

我实际上用它来声明不应该相关的 TransactionInterceptor