|
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 |
|
On Fri, Feb 24, 2012 at 11:44 AM, Rick R <[hidden email]> wrote:
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()) |
|
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 <[hidden email]>: > > > On Fri, Feb 24, 2012 at 11:44 AM, Rick R <[hidden email]> 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()) |
|
return ss.getObject() ! :)
2012/2/24 Eduardo Macarron <[hidden email]>: > 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 <[hidden email]>: >> >> >> On Fri, Feb 24, 2012 at 11:44 AM, Rick R <[hidden email]> 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()) |
|
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. On Fri, Feb 24, 2012 at 3:47 PM, Eduardo Macarron <[hidden email]> wrote: return ss.getObject() ! :) Rick R |
|
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 <[hidden email]>: > 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 > > http://forum.springsource.org/showthread.php?123527-Injection-of-Environment-not-happening-in-my-Import-config-class&p=403011#post403011 > > 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. > > > On Fri, Feb 24, 2012 at 3:47 PM, Eduardo Macarron > <[hidden email]> wrote: >> >> return ss.getObject() ! :) >> >> 2012/2/24 Eduardo Macarron <[hidden email]>: >> > 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 <[hidden email]>: >> >> >> >> >> >> On Fri, Feb 24, 2012 at 11:44 AM, Rick R <[hidden email]> 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()) > > > > > -- > Rick R |
|
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
On Sat, Feb 25, 2012 at 1:53 AM, Eduardo Macarron <[hidden email]> wrote: Hi Rick. MapperScannerConfigurer is a Rick R |
|
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. |
|
In reply to this post by Rick R
On Feb 24, 9:44 pm, Rick R <[hidden email]> wrote: > 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 what are you trying to achieve by creating multiple data sources, is it multi tenancy ? |
|
On Sat, Feb 25, 2012 at 12:22 PM, sudarshan <[hidden email]> wrote:
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
|
|
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 <[hidden email]>: > > > On Sat, Feb 25, 2012 at 12:22 PM, sudarshan <[hidden email]> 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 > https://jira.springsource.org/browse/SPR-8269 > > > -- > Rick R |
|
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 <[hidden email]> 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. > > 2012/2/25 Rick R <[hidden email]>: > > > > > > > > > > > On Sat, Feb 25, 2012 at 12:22 PM, sudarshan <[hidden email]> 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 > >https://jira.springsource.org/browse/SPR-8269 > > > -- > > Rick R |
|
In reply to this post by Eduardo Macarron
On Sat, Feb 25, 2012 at 1:29 PM, Eduardo Macarron <[hidden email]> wrote:
That is exactly the issue that caused our change, but now I recall 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.
|
|
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 <[hidden email]> wrote: > On Sat, Feb 25, 2012 at 1:29 PM, Eduardo Macarron < > > [hidden email]> 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. |
|
In reply to this post by Rick R
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 <[hidden email]>: > On Sat, Feb 25, 2012 at 1:29 PM, Eduardo Macarron > <[hidden email]> 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. > > |
|
In reply to this post by Eduardo Macarron
On Mon, Feb 27, 2012 at 11:58 AM, Eduardo <[hidden email]> wrote: Hi Rick! 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 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 |
|
In reply to this post by Iwao AVE!
On Mon, Feb 27, 2012 at 1:46 PM, Iwao AVE! <[hidden email]> wrote:
... 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.
|
|
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 <[hidden email]>: > > > On Mon, Feb 27, 2012 at 1:46 PM, Iwao AVE! <[hidden email]> 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. > > |
|
Hi guys. Seems that the scanner is not behaving fine with Spring java
config. Maybe we should re-think our strategy with the scanner. See the thread here: http://groups.google.com/group/mybatis-user/browse_thread/thread/2780fa15e5011990 ---------- Forwarded message ---------- From: Eduardo Macarron <[hidden email]> Date: 2012/2/27 Subject: Re: Spring3.1 issue when using Java Config (multiple datasources) ? To: [hidden email] 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 <[hidden email]>: > > > On Mon, Feb 27, 2012 at 1:46 PM, Iwao AVE! <[hidden email]> 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. > > |
|
In reply to this post by Rick R
On Mon, Feb 27, 2012 at 1:56 PM, Rick R <[hidden email]> wrote:
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 |
| Powered by Nabble | Edit this page |
