Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to use MyBatis-CDI with GlassFish 4 and 4.1 #11

Closed
pholding opened this issue Apr 6, 2015 · 12 comments
Closed

Unable to use MyBatis-CDI with GlassFish 4 and 4.1 #11

pholding opened this issue Apr 6, 2015 · 12 comments

Comments

@pholding
Copy link

pholding commented Apr 6, 2015

I'm unable to get MyBatis-CDI working with GlassFish 4 and GlassFish 4.1 due to a MybatisCdiConfigurationException exception being thrown with the description "There are no SqlSessionFactory producers properly configured."

The code for the SqlSessionFactory I'm using is as follow:

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 (lookup="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;
    }
}

I've stepped through the code of the MyBatis-CDI module and have found that when the follow line of code in CDIUtils findSqlSessionFactory(...) is executed it fails find any beans that return SqlSessionFactory.class.

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

I've tried running my program on GlassFish 4 and 4.1 and they both have the same problem, but it works fine if I run my program on WildFly 8.1. My first thought was that it might be a problem with the version of Weld shipped with Glassfish but it turns out that GlassFish 4.1 is running Weld version 2.2.2 whereas WildFly is running Weld version 2.1.2.

Is there anything I can do in GlassFish, my code or in the MyBatis-CDI module to overcome this problem when running in GlassFish?

@christianpoitras
Copy link
Member

Try adding @ApplicationScoped to your SqlSessionFactoryProvider.

@pholding
Copy link
Author

pholding commented Apr 7, 2015

I've just tried adding @ApplicationScoped to the SqlSessionFactoryProvider class but I'm still getting a MybatisCdiConfigurationException thrown with the description "There are no SqlSessionFactory producers properly configured."

@christianpoitras
Copy link
Member

I guess it will be difficult to find the reason why Weld behaves differently in 2.2.2 compared to 2.1.2.

My only other suggestion would be to force the declaration of the bean in beans.xml and see if that helps.
You could also try to add the Default and/or Any annotation to qualifiers.

beans = beanManager.getBeans(SqlSessionFactory.class, new AnnotationLiteral() {});

@pholding
Copy link
Author

pholding commented Apr 8, 2015

I've tried adding @Default and @Any to the method but the problem still remains.

I've also found out that there seems to be a GlassFish specific release of Weld, although I don't know what is different between the standard release and the GlassFish release, and there doesn't appear to be a GlassFish specific release of Weld 2.1.2 in Maven Central. I tried downloading the GlassFish release of Weld 2.2.10.SP1 from Maven Central (https://repo1.maven.org/maven2/org/jboss/weld/weld-osgi-bundle/2.2.10.SP1/) but that didn't fix the problem either.

Any idea how I would force the declaration of SqlSessionFactoryProvider in beans.xml? I've taken a look on Google but the only examples I can find are for declaring interceptors and decorators.

@christianpoitras
Copy link
Member

Normally, using

beans = beanManager.getBeans(SqlSessionFactory.class, new AnnotationLiteral() {});

CDI should return all SqlSessionFactory beans. To test this, you will need to create your own copy of mybatis-cdi.

After checking, it is not possible to force the declaration of a bean in beans.xml. You can only force the use of alternatives. I am not a CDI expert, sorry.

@pholding
Copy link
Author

pholding commented Apr 9, 2015

I've copied the various classes that make up mybatis-cdi directly into my program and have registered the extension in META-INF/services/javax.enterprise.inject.spi.Extension, and I can now successfully inject mappers into my program and run queries using MyBatis.

Given that this works in Weld without any changes and also in GlassFish when I copy the mybatis-cdi classes into my program, I'm wondering whether this is either a bug in GlassFish itself or the GlassFish specific release of Weld.

@christianpoitras
Copy link
Member

Thanks. That's an interesting bit of information. I'll have a look into it and see if there is anything to do to solve the issue.

@hazendaz
Copy link
Member

hazendaz commented May 6, 2015

Just a few ideas...

Could this have something to do with beans.xml not being setup for 2.2.x? While it is not required in glassfish 4.1, if I recall correctly, what it does changed. Annotations are default now.


Other possible issue is the fact that newer CDI no longer just injects things for sake of injection. It requires a scope regardless. @dependent is the scope that should be set on anything that is performing injection if no scope is to be listed meaning it is going to be part of some other scope. So lets us say the piece you didn't show where you are @Inject on the producer you have, does that class have a scope itself?

@fgianneschi
Copy link

I'm running WildFly 8.2.1 and I've the same problem. Any updates?

@sjljsw
Copy link

sjljsw commented Dec 30, 2015

hello ,I run glassfish 4.1 or payrar, the same and you have the same problem. You do not know the problem has been solved? I am very anxious to solve this problem.My weld-osgi-bundle upgrade to 2.3.2.final. Can not solve the problem.

I suspect that
beans = beanManager.getBeans(SqlSessionFactory.class, qualifiers.toArray(new Annotation[]{}));.
Can not find an instance

@quarkalone
Copy link

Hello,
I'm having a difficult time with glassfish 4.1. Does anyone have a working example? Currently, when I try to inject a mapper I get this message in the log:

Severe: Error Rendering View[/index.xhtml]
org.mybatis.cdi.MybatisCdiConfigurationException: There are no SqlSessionFactory producers properly configured.

However, some lines before I get:
Info: MyBatis CDI Module - Activated
Info: MyBatis CDI Module - Mapper dependency discovered: org.jayasoft.mapper.PersonaMapper

Regards.

@mnesarco
Copy link
Member

Hi, I have tested the beta5 against Payara 4.1 (Glassfish 4.1) and TomEE-Plus 7.0.1.
The test code can be found here: https://github.com/mnesarco/mybatis-cdi-samples

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants