MyBatis CDI beanManager.getBeans无法在GlassFish 4和4.1中找到SqlSessionFactory bean

时间:2015-04-05 17:44:09

标签: java glassfish cdi mybatis weld

我创建了一个简单的Java EE程序来试验MyBatis,但是我使用MyBatis CDI模块遇到了问题。我已按照http://mybatis.github.io/cdi/injection.html上列出的说明进行操作,但是当我的程序尝试使用MyBatis时,会引发MybatisCdiConfigurationException异常并附带描述&#34;没有正确配置SqlSessionFactory生成器。&#34; < / p>

我使用的SqlSessionFactory的代码如下:

import javax.annotation.Resource;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import javax.sql.DataSource;

import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;

public class SqlSessionFactoryProvider {

    @Resource (name="jdbc/MyDatabase")
    DataSource dataSource;

    @Produces
    @ApplicationScoped
    public SqlSessionFactory produceFactory() {
        TransactionFactory transactionFactory = new JdbcTransactionFactory();
        Environment environment = new Environment("development",
                transactionFactory, dataSource);
        Configuration configuration = new Configuration(environment);
        configuration.addMapper(ToDoItemMapper.class);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
                .build(configuration);
        return sqlSessionFactory;
    }
}

我已经逐步完成了MyBatis CDI模块的代码,并且发现当执行CDIUtils findSqlSessionFactory(...)中的以下代码行时,它找不到任何返回SqlSessionFactory.class.的bean

beans = beanManager.getBeans(SqlSessionFactory.class, qualifiers.toArray(new Annotation[]{}));

我尝试在GlassFish 4和4.1上运行我的程序,但它们都有同样的问题,但如果我在WildFly 8.1上运行我的程序,它就可以找到。我首先想到的是,Glassfish附带的Weld版本可能存在问题,但事实证明GlassFish 4.1正在运行Weld 2.2.2版,而WildFly正在运行Weld版本2.1.2。

在GlassFish中运行时,我可以在GlassFish,我的代码或MyBatis CDI模块中做些什么来克服这个问题?或者,任何人都可以建议我可以采取哪些措施来进一步调查问题吗?

2 个答案:

答案 0 :(得分:0)

我在尝试实现在Jboss wildfly中运行的mybatis-CDI时遇到了同样的问题。我通过这个git smaple项目找到了解决方案:https://github.com/artplastika/mybatis-cdi-example

您似乎唯一缺少的是SqlSessionFactoryProvider.java类上的@ Local,@ Stateless和@Named注释

请参阅Git示例中的SqlSessionFactoryProvider.java类:https://github.com/artplastika/mybatis-cdi-example/blob/master/mybatis-cdi-example-ejb/src/main/java/org/mybatis/cdi/example/beans/SqlSessionFactoryProviderImpl.java

您还应该确保在src / main / resources / META-INF文件夹中有beans.xml

修改

我的Maven依赖设置:

<dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
            <scope>compile</scope>
        </dependency>
        <!-- Import the CDI API -->
        <dependency>
            <groupId>javax.enterprise</groupId>
            <artifactId>cdi-api</artifactId>
            <version>1.2</version>
            <scope>compile</scope>
        </dependency>
        <!-- Mybatis Dependencies -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.2.5</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-cdi</artifactId>
            <version>1.0.0-beta1</version>
            <scope>compile</scope>
        </dependency>
        <!-- Below Dependencies are very specific to Jboss due to class conflicts if you dont have the exclusions specified -->
        <!-- Proxy support (Mandatory) -->
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <scope>compile</scope>
            <version>2.2.2</version>
            <exclusions>
                <exclusion>
                    <groupId>asm</groupId>
                    <artifactId>asm</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- Internal dependency (Required) -->
        <dependency>
            <groupId>org.ow2.asm</groupId>
            <artifactId>asm-util</artifactId>
            <version>5.0.3</version>
            <scope>compile</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.ow2.asm</groupId>
                    <artifactId>asm</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- Internal dependency (Required) -->
        <dependency>
            <groupId>opensymphony</groupId>
            <artifactId>oscache</artifactId>
            <version>2.4</version>
            <scope>compile</scope>
            <!-- This excludes the transitive dependency on JMS -->
            <exclusions>
                <exclusion>
                    <groupId>javax.jms</groupId>
                    <artifactId>jms</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

我的样本工厂制作人如下:

@Stateless
@Local(SampleSqlSessionFactoryProvider.class)
public class SampleSqlSessionFactoryProvider {
    @Produces
    @ApplicationScoped
    @Named("sqlSessionFactory")
    public SqlSessionFactory produceFactory() throws Exception {        
        Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = null;
        String environment = "default";
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader, environment);
        return sqlSessionFactory;
    }
}

并使用它我按如下方式注入:

@Local(DaoBean.class)
@Stateless
public class DoaBean{
     private @Inject @Named("sqlSessionFactory") SqlSession session;
     public void doStuff(){
         session.selectOne(...);
     }
     ...
}

答案 1 :(得分:0)

我找到了解决这个问题的方法,但实际上并不是我希望的解决方案。我已经将构成mybatis-cdi的各个类直接复制到我的程序中,并在META-INF/services/javax.enterprise.inject.spi.Extension中注册了扩展名,现在我可以成功地将mappers注入我的程序并使用MyBatis运行查询。

我在MyBatis-CDI GitHub存储库中将其作为issue引发,如果有修复,则会更新此答案。