Spring3.1 issue when using Java Config (multiple datasources) ?

2,273 views
Skip to first unread message

Rick R

unread,
Feb 24, 2012, 11:44:07 AM2/24/12
to mybati...@googlegroups.com
I'm attempting to use mybatis-spring 1.0.2 with Spring3.1 and I'm having difficulty trying to figure out the best way to get multiple datasources set up using pure Java configuration.

The current issue is using a Java config I can't set a SqlSessionFactoryBean on an instance of MapperScannerConfigurer (although as you'll see at the end in 1.0.0 and xml config you could pass an instance of SqlSessionFactoryBean to the setter setSqlSessionFactory on MapperScannerConfigurer).  My guess is the issue is in Spring 3.1 when a class like SqlSessionFactoryBean implements  org.springframework.beans.factory.FactoryBean and not the direct type?) 

It wold be a shame though not to be able to leverage a pure Java config so I'm curious what work arounds there are? 

Currently trying:

@Configuration
public class PersistenceConfig {
@Inject
private Environment environment;

@Bean
public PlatformTransactionManager transactionalManagerOne() {
return new DataSourceTransactionManager(dataSourceOne()); 
}

@Bean
public DataSource dataSourceOne() {
BasicDataSource ds = new BasicDataSource();
ds.setUsername(environment.getProperty("db1.username"));
//..others
return ds;
}

@Bean
SqlSessionFactoryBean sqlSessionFactoryBeanOne() {
SqlSessionFactoryBean ss = new SqlSessionFactoryBean();
ss.setDataSource(dataSourceOne());
ss.setTypeAliasesPackage("net.learntechnology.empmaint.domain");
return ss;
}

@Bean
MapperScannerConfigurer hsqlDBmapperScannerConfigurer() {
MapperScannerConfigurer sc = new MapperScannerConfigurer();
sc.setBasePackage("net.learntechnology.empmaint.persistence");
sc.setAnnotationClass(OurHsqlDB.class);

//******* can't do :
//sc.setSqlSessionFactoryBean(sqlSessionFactoryBeanOne());
//can do setSqlSessionFactory or setSqlSessionTemplate() 
                //but they don't take SqlSessionFactoryBean 
return sc;
}


Howevrr using mybatis-spring 1.0.0, and an xml config I could so such a thing:

 
<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="db1SessionFactoryBean">
<property name="dataSource" ref="db1dataSource" />
<property name="configLocation" value="classpath:mybatis-db1-config.xml" />
</bean>

<!-- will attach the correct sqlSessionFactory based on the annotation used on the Mapper -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="foo.service.mapper" />
<property name="annotationClass" value="foo.service.annotation.OracleDB1" />
         <!-- **** WORKS: --->
<property name="sqlSessionFactory" ref="db1SessionFactoryBean"/>
</bean>


--
Rick R

Rick R

unread,
Feb 24, 2012, 11:58:27 AM2/24/12
to mybati...@googlegroups.com
On Fri, Feb 24, 2012 at 11:44 AM, Rick R <ric...@gmail.com> wrote:
 
@Bean
SqlSessionFactoryBean sqlSessionFactoryBeanOne() {
SqlSessionFactoryBean ss = new SqlSessionFactoryBean();
ss.setDataSource(dataSourceOne());
ss.setTypeAliasesPackage("net.learntechnology.empmaint.domain");
return ss;
}

@Bean
MapperScannerConfigurer hsqlDBmapperScannerConfigurer() {
MapperScannerConfigurer sc = new MapperScannerConfigurer();
sc.setBasePackage("net.learntechnology.empmaint.persistence");
sc.setAnnotationClass(OurHsqlDB.class);

//******* can't do :
//sc.setSqlSessionFactoryBean(sqlSessionFactoryBeanOne());


Would it work if I just return SqlSessionFactoryBean and attempt to brute force it cast to SqlSessionFactory? (I'm not exactly sure how the org.springframework.beans.factory.FactoryBean concept works but I'll try this and see what happens. Doesn't seem like the ideal though.)

@Bean
public SqlSessionFactory sqlSessionFactoryBeanOne() {
SqlSessionFactoryBean ss = new SqlSessionFactoryBean();
ss.setDataSource(dataSourceOne());
ss.setTypeAliasesPackage("net.learntechnology.empmaint.domain");
return (SqlSessionFactory)ss;

...
mapperScanner.setSqlSessionFactory(sqlSessionFactoryBeanOne())

Eduardo Macarron

unread,
Feb 24, 2012, 3:46:49 PM2/24/12
to mybati...@googlegroups.com
Hi Rick,

A factory bean is a trick to set up factories instead of beans when
using XML. In the case of MyBatis we need to build SqlSesionFactories
so instead of using a SqlSessionFactoryBuilder we use an Spring's
SqlSessionFactoryBean.

A factory bean returns and object when getObject() is called. So you should try:

public SqlSessionFactory sqlSessionFactoryBeanOne() {
SqlSessionFactoryBean ss = new SqlSessionFactoryBean();
ss.setDataSource(dataSourceOne());
ss.setTypeAliasesPackage("net.learntechnology.empmaint.domain");

ss.getObject();
}

hope this helps!
2012/2/24 Rick R <ric...@gmail.com>:

Eduardo Macarron

unread,
Feb 24, 2012, 3:47:07 PM2/24/12
to mybati...@googlegroups.com
return ss.getObject() ! :)

2012/2/24 Eduardo Macarron <eduardo....@gmail.com>:

Rick R

unread,
Feb 24, 2012, 11:57:01 PM2/24/12
to mybati...@googlegroups.com
Thanks Eduardo. Although man, I've been stumped ALL day on something that I think has to be related to the MapperScannerConfigurer. Somehow it's really messing with the ability for me to using Spring 3.1's ability to set the Environment when within a jar file. If you scroll down to the bottom of this thread you could see the conclusion I came to at the very end


Here is the source code https://www.sugarsync.com/pf/D7754172_2045968_80697 I'm trying to work with if you get energetic and want to see what I'm talking about. As a summary here is the class that has the issues http://pastie.org/3452588 If that MapperScannerConfigurer is commented out then the Environment property CAN be injected. If it's left "as is" then it's not. Took me forever to figure this out since there weren't any errors so I thought it was somehow related to Spring3.1 and using a jar within my war where I wanted Environment injected.

If MapperScannerConfigurer is the culprit this will be a serious issue for those wanting to use it with Spring3.1 using a Java based config with injecting Environment. Not sure of course where the exact issue is coming from but I do know when that declaration is commented out I see Environment as not null.

Thanks again for any help with this.
--
Rick R

Eduardo Macarron

unread,
Feb 25, 2012, 1:53:56 AM2/25/12
to mybati...@googlegroups.com
Hi Rick. MapperScannerConfigurer is a
BeanDefinitionRegistryPostProcessor and honestly I don't know how well
it will play with @Configuration.

Classpath scanners are special beans. For example, I may be wrong, but
Spring Data JPA uses a similar scanner that is a
JpaRepositoryNameSpaceHandler. That means that it is an XML namespace
processor. Will that work with @Configuration? Not sure but probably
not :)

There is an small change in Spring 1.1.0 suggested by the Spring team.
I am fairly sure it will behave the same but I may give it a try (it
needs MB 3.1.0 still in snapshot).

So if you can, I would try how this works with XML.

2012/2/25 Rick R <ric...@gmail.com>:

Rick R

unread,
Feb 25, 2012, 10:25:49 AM2/25/12
to mybati...@googlegroups.com
I tried doing a hybrid approach were most my config is in Java and then I import the MapperScannerConfigurer...

@ImportResource("classpath:mapper-scanner.xml")
public class PersistenceConfig {

//mapper-scanner.xml
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="net.learntechnology.empmaint.mapper.ourDB"/>
<property name="sqlSessionFactory" ref="sqlSessionFactoryBeanOne"/>
</bean>

Still causes issues. Are you aware of anyone using MyBatis with Spring3.1 and Java configuration vs XML? Spring 3.0 had it as well so I figure others must be using it?

I'll try a pure XML approach to be sure things are working there with Spring3.1

I just tried to use the 1.1.0-SNAPSHOT but it doesn't seem to be in the mybatis snapshot repo? In the meantime I downloaded it manually and pushed it to my local repo but then I needed to also included the dependency to the core mybatis library which I included (3.0.6), but then things blew up when trying to set the SqlSessionFactory bean (looks like its trying to call setDatabaseId on Configuration which it can't.)

Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.apache.ibatis.session.SqlSessionFactory net.learntechnology.empmaint.spring.PersistenceConfig.sqlSessionFactoryBeanOne()] threw exception; nested exception is java.lang.NoSuchMethodError: org.apache.ibatis.session.Configuration.setDatabaseId(Ljava/lang/String;)V
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:169)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:570)
... 48 more
Caused by: java.lang.NoSuchMethodError: org.apache.ibatis.session.Configuration.setDatabaseId(Ljava/lang/String;)V
at org.mybatis.spring.SqlSessionFactoryBean.buildSqlSessionFactory(SqlSessionFactoryBean.java:393)
at org.mybatis.spring.SqlSessionFactoryBean.afterPropertiesSet(SqlSessionFactoryBean.java:293)
at org.mybatis.spring.SqlSessionFactoryBean.getObject(SqlSessionFactoryBean.java:433)
at net.learntechnology.empmaint.spring.PersistenceConfig.sqlSessionFactoryBeanOne(PersistenceConfig.java:65)
at net.learntechnology.empmaint.spring.PersistenceConfig$$EnhancerByCGLIB$$61c9ad10.CGLIB$sqlSessionFactoryBeanOne$2(<generated>)
at net.learntechnology.empmaint.spring.PersistenceConfig$$EnhancerByCGLIB$$61c9ad10$$FastClassByCGLIB$$6cf97d2d.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:215)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:280)
at net.learntechnology.empmaint.spring.PersistenceConfig$$EnhancerByCGLIB$$61c9ad10.sqlSessionFactoryBeanOne(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:149)
... 49 more
--
Rick R

Eduardo

unread,
Feb 25, 2012, 10:30:53 AM2/25/12
to mybatis-user

Hi Rick, MyBatis-Spring 1.1.0 is still in progress there is only an
snapshot available and it depends on MB 3.1.0 (also in snapshot).

Try better the XML way or use MapperFactoryBeans instead of the
scanner and let us know.

sudarshan

unread,
Feb 25, 2012, 12:22:12 PM2/25/12
to mybatis-user
@ Rick what are you trying to achieve by creating multiple data
sources, is it multi tenancy ?

Rick R

unread,
Feb 25, 2012, 1:21:15 PM2/25/12
to mybati...@googlegroups.com


On Sat, Feb 25, 2012 at 12:22 PM, sudarshan <sudar...@gmail.com> wrote:

 
@ Rick what are you trying to achieve by creating multiple data
sources, is it multi tenancy ?

The application needs to interact with more than one database (I don't need JTA though.. not transactions across multiple DBs.)  
It's easy to setup with MyBatis, just having the issue now with the MapperConfig stuff.

@Eduaro
This jira ticket looks like it's related to the same thing I'm noticing (yet marked resolved.) Yet I'm using 3.1.0-RELEASE, so not sure if it's exactly the same

Eduardo Macarron

unread,
Feb 25, 2012, 1:29:04 PM2/25/12
to mybati...@googlegroups.com
That is exactly the issue that caused our change, but now I recall
that change was made for 1.0.2 so you are using the right version. No
need to go 1.1.0.

If the number of databases is known XML should work fine.

2012/2/25 Rick R <ric...@gmail.com>:

sudarshan

unread,
Feb 26, 2012, 4:52:22 AM2/26/12
to mybatis-user
Even if the number of databases is know in advance how can we make
MapperScannerConfigurer to point to the required database at run
time ?

I mean if i have 2 users, when user 1 logs in it should point to
User1DB and when user 2 logs in it should point to User2DB.

Hibernate 4 has come up with multi tenancy support, does Mybatis have
something similar on its road map ?

On Feb 25, 11:29 pm, Eduardo Macarron <eduardo.macar...@gmail.com>
wrote:

Rick R

unread,
Feb 27, 2012, 10:46:10 AM2/27/12
to mybati...@googlegroups.com
On Sat, Feb 25, 2012 at 1:29 PM, Eduardo Macarron <eduardo....@gmail.com> wrote:
That is exactly the issue that caused our change, but now I recall
that change was made for 1.0.2 so you are using the right version. No
need to go 1.1.0.

If the number of databases is known XML should work fine.


Yes XML works fine, BUT you seem to have to go "all XML"  if you plan to use the MapperScannerConfigurer (at least from my preliminary tests.)

I was hoping a hybrid approach "might" work, where I could just code the xml for the persistence mybatis stuff but then use Java config for the rest of the application (eg the web app portion.) So for the web config I'd attempt to import the services-config.xml as shown below. The following would work if not using the MapperScannerConfigurer.

@Configuration
@ImportResource("classpath:/services-config.xml")
@ComponentScan(basePackages = "foo.bar.package", excludeFilters = {@ComponentScan.Filter(Configuration.class)})
@PropertySource("application.properties")
@EnableTransactionManagement
@EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurerAdapter {

Where "services-config.xml" was the mybatis stuff. The issue is using the MapperScannerConfigurer defined in xml still breaks your autowiring (Maybe the mybatis snapshot fixes things, I hadn't tried too much with that version since it seemed more of a pain to get going with using Maven.)

The above will work just fine if you decided to not use MapperSannerConfigurer and instead used MapperFactoryBeans in your xml:

<bean id="employeeMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="net.learntechnology.empmaint.business.dbone.mapper.EmployeeMapper" />
<property name="sqlSessionFactory" ref="sqlSessionFactoryOne" />
</bean>


So right now it sort of throws the entire MapperScannerConfigurer out of the water if you want to use any Java configuration which is a shame. The benefits of using the MapperScannerConfigurer seem really nice.

I also was trying to use a pure Java approach, and not using MappserScannerConfigurer and defining even the MyBatis config in Java, but ran into issues trying to use a Java config for defining my Mappers.... I thought something like this would work:

@Bean
public EmployeeMapper employeeMapper() throws Exception {
MapperFactoryBean bean = new MapperFactoryBean();
bean.setMapperInterface(EmployeeMapper.class);
bean.setSqlSessionFactory(sqlSessionFactoryBeanOne());
return (EmployeeMapper)bean.getObject();
}

but I end up with:

org.apache.ibatis.binding.BindingException: Type interface net.learntechnology.empmaint.business.dbone.mapper.EmployeeMapper is not known to the MapperRegistry.

Hopefully I'm just missing something obvious? 

I'll probably have to stick with all XML anyway since I like the MapperScannerConfigurer. If it can't be worked out with using Java Configuration, it definitely should be mentioned in the docs (if it's not already) since I think with Spring3.1 you'll see more people using Java configuration over XML.


Eduardo

unread,
Feb 27, 2012, 11:58:16 AM2/27/12
to mybatis-user
Hi Rick!

I think you need to call explicitly to afterPropertiesSet()

@Bean
public EmployeeMapper employeeMapper() throws Exception {
MapperFactoryBean<EmployeeMapper> bean = new
MapperFactoryBean<EmployeeMapper>();
bean.setMapperInterface(EmployeeMapper.class);
bean.setSqlSessionFactory(sqlSessionFactoryBeanOne());
bean.afterPropertiesSet();
return bean.getObject();

Regarding the use of java config with the scanner, honestly we did not
know if it works or not yet :) I usually do not use the java config
but hope I can have look at this. How do the out-of-the box component
scan work in with java config? is that supported?


On 27 feb, 16:46, Rick R <ric...@gmail.com> wrote:
> On Sat, Feb 25, 2012 at 1:29 PM, Eduardo Macarron <
>
> eduardo.macar...@gmail.com> wrote:
> > That is exactly the issue that caused our change, but now I recall
> > that change was made for 1.0.2 so you are using the right version. No
> > need to go 1.1.0.
>
> > If the number of databases is known XML should work fine.
>
> Yes XML works fine, BUT you seem to have to go "all XML"  if you plan to
> use the MapperScannerConfigurer (at least from my preliminary tests.)
>
> I was hoping a hybrid approach "might" work, where I could just code the
> xml for the persistence mybatis stuff but then use Java config for the rest
> of the application (eg the web app portion.) So for the web config I'd
> attempt to import the services-config.xml as shown below. The following
> would work if not using the MapperScannerConfigurer.
>
> @Configuration
> @ImportResource("classpath:/services-config.xml")
> @ComponentScan(basePackages = "foo.bar.package", excludeFilters =
> {...@ComponentScan.Filter(Configuration.class)})

Iwao AVE!

unread,
Feb 27, 2012, 1:46:22 PM2/27/12
to mybati...@googlegroups.com
Hi Rick,

A while ago, I tried the Java config, but had to switch to Java + XML
hybrid configuration after I found of SPR-8269.
I will show you my config, but I am not sure if this is helpful
because I don't use Spring MVC or multiple data sources.

Anyway, my XML config defines the @Configuration bean and the
MapperScannerConfigurer with its dependencies.

<context:annotation-config />
<context:property-placeholder />
<aop:aspectj-autoproxy />
<tx:annotation-driven />
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:MyBatisConfig.xml" />
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="mycompany.mapper" />
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
... other DBCP properties
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean class="mycompany.AppConfig" />

And the other configurations are done with Java config (not much in my case).

@Configuration
@ComponentScan("mycompany.service")
public class AppConfig {
@Autowired
private Environment env;

@Bean
public SomeBean beanName() {
...

In my web.xml, I have ContextLoaderListener as a listener and
contextInitializerClasses as a context-param which prepares my
Environment.

And that's all, I think (it's been a while since I edited these config files).

Hope this helps,
Iwao

2012/2/28 Rick R <ric...@gmail.com>:

Rick R

unread,
Feb 27, 2012, 1:51:02 PM2/27/12
to mybati...@googlegroups.com
On Mon, Feb 27, 2012 at 11:58 AM, Eduardo <eduardo....@gmail.com> wrote:
Hi Rick!

I think you need to call explicitly to afterPropertiesSet()

@Bean
public EmployeeMapper employeeMapper() throws Exception {
MapperFactoryBean<EmployeeMapper> bean = new
MapperFactoryBean<EmployeeMapper>();
bean.setMapperInterface(EmployeeMapper.class);
bean.setSqlSessionFactory(sqlSessionFactoryBeanOne());
bean.afterPropertiesSet();
return bean.getObject();


Excellent. That enabled an EmployeeMapper to work. Although, I still don't want to have to code one of them for each Mapper (even leveraging some inheritance to a parent - I'd still need at least one entry for each Mapper.)
 
Regarding the use of java config with the scanner, honestly we did not
know if it works or not yet :) I usually do not use the java config
but hope I can have look at this. How do the out-of-the box component
scan work in with java config? is that supported?

Out of box component scan is just fine with Java config. I simply can't get the MapperConfigurer to work however, and have been trying for too long :(

I'm either going to have to:

1) Use all XML for everything
or
2) Use Java config but then manually having to declare each mapper in my Java config. 

Given those two options, I'll have to go back to XML I guess.

I'm still thinking there is probably some obscure thing I'm missing to get the MapperConfigurer to work with a Java config approach.



--
Rick R

Rick R

unread,
Feb 27, 2012, 1:56:48 PM2/27/12
to mybati...@googlegroups.com


On Mon, Feb 27, 2012 at 1:46 PM, Iwao AVE! <hara...@gmail.com> wrote:
...

<bean class="mycompany.AppConfig" />

And the other configurations are done with Java config (not much in my case).
 

That's not a bad idea to try. What I'll try is have my web.xml define an app-config.xml 
 and in there try...

//app-config.xml
<import resource="classpath:my-mybatis-config.xml"/>
<bean class="foo.MyWebJavaConfig"/>

I wouldn't want to declare my mybatis config in my web.xml context and then have it be responsible for loading the web java config since that tightly couples them together in an backwards way (although not super critical I guess.) Hopefully the import approach above will work.


Eduardo Macarron

unread,
Feb 27, 2012, 2:07:01 PM2/27/12
to mybati...@googlegroups.com
Having a look at 3.1 code I see there is a
ComponentScanAnnotationParser for that purpose.

They use the ComponentScanAnnotationParser for @ComponentScan
and the ContextNamespaceHandler/ComponentScanBeanDefinitionParser for
XML config.

Maybe we should go that strategy and build our own mybatis
namespace... and maybe an @MyBatisMapperScan annotation.

2012/2/27 Rick R <ric...@gmail.com>:

Message has been deleted

Rick R

unread,
Feb 27, 2012, 2:28:50 PM2/27/12
to mybati...@googlegroups.com
This worked great Iwao....
in web.xml...
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:application-config.xml</param-value>
</context-param>

Then... application-config.xml
 
<beans  ....>

<import resource="classpath:/services-config.xml"/>                                 <!-- MyBatis config for persistence jar -->
<bean class="net.learntechnology.empmaint.web.config.WebMvcConfig"/>  <!-- Java web config -->

</beans> 

This now gives me:

All xml for MyBatis so I can get component scanning
AND
Java config for everything else.

Great suggestion Iwao!

Ideally though of course Spring-MyBatis should be able to support full Java configuration. It's a pretty big selling point of 3.1 so once that MapperConfigurer is worked out it'll be really nice. In the meantime though I'm content with this above solution.


--
Rick R

Iwao AVE!

unread,
Feb 28, 2012, 10:42:26 AM2/28/12
to mybati...@googlegroups.com
Hi Rick,

Thanks for the feedback.
I didn't spend much time as eliminating XML was not my goal, but I agree that full java config would be a nice option.

// Iwao

2012/2/28 Rick R <ric...@gmail.com>:

Rick R

unread,
Mar 1, 2012, 12:52:53 PM3/1/12
to mybati...@googlegroups.com
web.xml...
<context-param>
       <param-name>contextConfigLocation</param-name>
       <param-value>classpath:application-config.xml</param-value>
</context-param>

 application-config.xml...

<beans  ....> 
       <import resource="classpath:/services-config.xml"/>                                 <!-- MyBatis config for persistence jar -->
       <bean class="net.learntechnology.empmaint.web.config.WebMvcConfig"/>  <!-- Java web config -->
</beans> 


Wow I spoke too soon. This is really really bad. MapperScannerConfigurer has become a major thorn in my side. Although you can now get a 'bit' further when defining things like Iwao described (and shown above) you are STILL stuck with properties not being set when you either:

A) Have ANY Java based @Configuration class. It doesn't seem to matter how you try to get to it (eg as a bean declaration in an xml file or with ContextConfiguration in your web.xml)

OR

B) (and this is the one that seems really crazy)... If you use a MapperScannerConfigurer in XML *BUT* it's part of a different xml file that you import - it seems unable to pick up any properties file! However, if you have just ONE big xml config (combining web with a mybatis spring config) then it works just fine?  I can post an example if need be.  

In this latter case I have my web config as xml and then in that web config I import my "mybatis-spring-config.xml."  If within mybatis-spring-config.xml I switch between using the MapperScannerConfigurer to MapperFactoryBean then properties are picked up just fine. If I use the MapperScannerConfigurer then they are not.

But why does it matter if it's used as an import or not? If I move all the content from the mybatis-spring-config.xml to the web-config.xml then YOU CAN use MapperScannerConfigurer and the properties are picked up just fine. It can't be how the import file is set up since, as mentioned, when I switch to a MapperFactoryBean in the imported config, the properties are set just fine.

So now it looks like I'm back being stuck using a MapperFactoryBean for every Mapper since it's important to me to have the mybatis-config.xml sit within the jar file. Users of the services jar should only have to provide a proper datasource properties file on their classpath and shouldn't have to be exposed to all the mybatis config stuff.

If anyone has a sample 3.1 Spring app using  MapperScannerConfigurer and the mybatis implementations within its own jar (with some properties injected from a properties file on the classpath)  please let me know what you did to get things to work (where this mybatis jar is used within a webapp.)

Rick R

unread,
Mar 1, 2012, 2:25:29 PM3/1/12
to mybati...@googlegroups.com
So for now I'm back to just using an all Java configuration and the relevant mybatis config looks like: (not sure if there is a better way to handle the below without the cast, but this is working- drawback of course being I need to define each Mapper in this config.):
        
        //will be used by all Mappers needing to use "DB One"
private MapperFactoryBean dbOneMapperFactoryBean(Class c) {
MapperFactoryBean bean = new MapperFactoryBean();
bean.setSqlSessionFactory(sqlSessionFactoryBeanOne());
bean.setMapperInterface(c);
bean.afterPropertiesSet();
return bean;
}

@Bean
public EmployeeMapper employeeMapper() throws Exception {
return (EmployeeMapper)dbOneMapperFactoryBean(EmployeeMapper.class).getObject();
}

       @Bean
       public SomeOtherMapper someOtherMapper.....  etc
--
Rick R

Eduardo Macarron

unread,
Mar 1, 2012, 2:48:41 PM3/1/12
to mybati...@googlegroups.com
Hi Rick, the scanner runs before the PropertyPlaceHolderConfigurer.
There is a workaround for this in 1.1.0. Instead of setting the
SqlSessionFactory reference you can set the name using
SqlSesionFactoryName. That makes PropertyPlaceHolderConfigurer work
again.

Have a look at:
http://www.mybatis.org/spring/mappers.html

2012/3/1 Rick R <ric...@gmail.com>:

Rick R

unread,
Mar 1, 2012, 4:44:10 PM3/1/12
to mybati...@googlegroups.com
On Thu, Mar 1, 2012 at 2:48 PM, Eduardo Macarron <eduardo....@gmail.com> wrote:
Hi Rick, the scanner runs before the PropertyPlaceHolderConfigurer.
There is a workaround for this in 1.1.0. Instead of setting the
SqlSessionFactory reference you can set the name using
SqlSesionFactoryName. That makes  PropertyPlaceHolderConfigurer work
again.

Have a look at:
http://www.mybatis.org/spring/mappers.html

Where's the workaround? I don't see it on the page provided in that link?
Thanks



--
Rick R

Rick R

unread,
Mar 1, 2012, 5:12:00 PM3/1/12
to mybati...@googlegroups.com
On Thu, Mar 1, 2012 at 4:44 PM, Rick R <ric...@gmail.com> wrote:
>
> On Thu, Mar 1, 2012 at 2:48 PM, Eduardo Macarron <eduardo....@gmail.com> wrote:
>>
>> Hi Rick, the scanner runs before the PropertyPlaceHolderConfigurer.
>> There is a workaround for this in 1.1.0. Instead of setting the
>> SqlSessionFactory reference you can set the name using
>> SqlSesionFactoryName. That makes  PropertyPlaceHolderConfigurer work
>> again.
>>
>> Have a look at:
>> http://www.mybatis.org/spring/mappers.html
>
>
> Where's the workaround? I don't see it on the page provided in that link?


Oh I see try to use 1.1.0 and use sqlSessionFactoryBeanName in lieu of
sqlSessionFactory for setting the MapperScannerConfigurer

I'll see if I could get 1.1.0 working. thanks.


--
Rick R

Rick R

unread,
Mar 4, 2012, 6:30:19 PM3/4/12
to mybati...@googlegroups.com
On Thu, Mar 1, 2012 at 2:48 PM, Eduardo Macarron
<eduardo....@gmail.com> wrote:
> Hi Rick, the scanner runs before the PropertyPlaceHolderConfigurer.
> There is a workaround for this in 1.1.0. Instead of setting the
> SqlSessionFactory reference you can set the name using
> SqlSesionFactoryName. That makes  PropertyPlaceHolderConfigurer work
> again.
>
> Have a look at:
> http://www.mybatis.org/spring/mappers.html

Just to keep this thread for reference when people are searching...

Using mybatis 3.1 snapshot and mybatis-spring 1.1.0 snapshot, I was
able to at use an xml config for mybatis AND a Java config for my web
app, so thanks for recommending that.


[ Side question(s), I had to download both snapshots and install them
manually. Is there a public snapshots repo for both projects? I
couldn't seem to find a valid one. Also, how close are both to being
officially released? Not trying to be too picky, but since 3.1 and
1.1.0 sound like nice releases it would be great to squeeze in the
ability to use mybatis-spring with a Java config if possible into the
release. Not sure how much work that involves though. ]

Eduardo Macarron

unread,
Mar 5, 2012, 12:45:21 AM3/5/12
to mybati...@googlegroups.com
Rick, there used to be an snapshot repo in sonatype but it works
inttermitently :( Anyway both core and spring are ready for release I
hope we can release them the next weekend.

2012/3/5 Rick R <ric...@gmail.com>:

Reply all
Reply to author
Forward
0 new messages