MyBatis CDI beanManager.getBeans 在 GlassFish 4 和 4.1 中找不到 SqlSessionFactory bean
MyBatis CDI beanManager.getBeans fails to find SqlSessionFactory bean in GlassFish 4 and 4.1
我创建了一个简单的 Java EE 程序来试验 MyBatis,但是我在使用 MyBatis CDI 模块时遇到了问题。我已按照 http://mybatis.github.io/cdi/injection.html 上列出的说明进行操作,但是当我的程序尝试使用 MyBatis 时,会抛出一个 MybatisCdiConfigurationException
异常,其描述为 "There are no SqlSessionFactory producers properly configured."
我使用的 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(...)
中的以下代码行时,它无法找到任何 return SqlSessionFactory.class.
beans = beanManager.getBeans(SqlSessionFactory.class, qualifiers.toArray(new Annotation[]{}));
我已经尝试 运行在 GlassFish 4 和 4.1 上运行我的程序,它们都有同样的问题,但是如果我 运行 我在 WildFly 8.1 上运行我的程序,它会起作用。我的第一个想法是,这可能是 Glassfish 附带的 Weld 版本有问题,但事实证明 GlassFish 4.1 是 运行ning Weld 2.2.2 版,而 WildFly 是 运行ning Weld 2.1 版。 2.
在 GlassFish 中 运行ning 时,我可以在 GlassFish、我的代码或 MyBatis CDI 模块中做些什么来克服这个问题?或者有人可以建议我可以做些什么来进一步调查这个问题吗?
我 运行 在尝试在 Jboss wildfly 中实现 mybatis-CDI 运行 时遇到了同样的问题。我在完成这个 git smaple 项目时找到了解决方案:https://github.com/artplastika/mybatis-cdi-example
您似乎唯一缺少的是 SqlSessionFactoryProvider.java class
上的 @Local、@Stateless 和 @Named 注释
参见Git例子中的SqlSessionFactoryProvider.javaclass:https://github.com/artplastika/mybatis-cdi-example/blob/master/mybatis-cdi-example-ejb/src/main/java/org/mybatis/cdi/example/beans/SqlSessionFactoryProviderImpl.java
您还应该确保 beans.xml 在您的 src/main/resources/META-INF 文件夹中
编辑
我的 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>
我有如下示例 Factory Producer:
@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(...);
}
...
}
我找到了解决此问题的方法,但并不是我所希望的解决方案。我已经将构成 mybatis-cdi 的各种 类 直接复制到我的程序中,并在 META-INF/services/javax.enterprise.inject.spi.Extension
中注册了扩展,现在我可以成功地将映射器注入我的程序和 运行 查询使用 MyBatis。
我在 MyBatis-CDI GitHub 存储库中将其作为 issue 提出,如果有修复,我会更新此答案。
我创建了一个简单的 Java EE 程序来试验 MyBatis,但是我在使用 MyBatis CDI 模块时遇到了问题。我已按照 http://mybatis.github.io/cdi/injection.html 上列出的说明进行操作,但是当我的程序尝试使用 MyBatis 时,会抛出一个 MybatisCdiConfigurationException
异常,其描述为 "There are no SqlSessionFactory producers properly configured."
我使用的 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(...)
中的以下代码行时,它无法找到任何 return SqlSessionFactory.class.
beans = beanManager.getBeans(SqlSessionFactory.class, qualifiers.toArray(new Annotation[]{}));
我已经尝试 运行在 GlassFish 4 和 4.1 上运行我的程序,它们都有同样的问题,但是如果我 运行 我在 WildFly 8.1 上运行我的程序,它会起作用。我的第一个想法是,这可能是 Glassfish 附带的 Weld 版本有问题,但事实证明 GlassFish 4.1 是 运行ning Weld 2.2.2 版,而 WildFly 是 运行ning Weld 2.1 版。 2.
在 GlassFish 中 运行ning 时,我可以在 GlassFish、我的代码或 MyBatis CDI 模块中做些什么来克服这个问题?或者有人可以建议我可以做些什么来进一步调查这个问题吗?
我 运行 在尝试在 Jboss wildfly 中实现 mybatis-CDI 运行 时遇到了同样的问题。我在完成这个 git smaple 项目时找到了解决方案:https://github.com/artplastika/mybatis-cdi-example
您似乎唯一缺少的是 SqlSessionFactoryProvider.java class
上的 @Local、@Stateless 和 @Named 注释参见Git例子中的SqlSessionFactoryProvider.javaclass:https://github.com/artplastika/mybatis-cdi-example/blob/master/mybatis-cdi-example-ejb/src/main/java/org/mybatis/cdi/example/beans/SqlSessionFactoryProviderImpl.java
您还应该确保 beans.xml 在您的 src/main/resources/META-INF 文件夹中
编辑
我的 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>
我有如下示例 Factory Producer:
@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(...);
}
...
}
我找到了解决此问题的方法,但并不是我所希望的解决方案。我已经将构成 mybatis-cdi 的各种 类 直接复制到我的程序中,并在 META-INF/services/javax.enterprise.inject.spi.Extension
中注册了扩展,现在我可以成功地将映射器注入我的程序和 运行 查询使用 MyBatis。
我在 MyBatis-CDI GitHub 存储库中将其作为 issue 提出,如果有修复,我会更新此答案。