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

All interfaces are registered as mybatis mappers even if they are not mappers #46

Closed
emacarron opened this issue Apr 5, 2016 · 18 comments
Assignees
Labels
Milestone

Comments

@emacarron
Copy link
Member

Right now, the mybatis boot starter module takes all the interfaces it founds in a project and registers them as mappers. We should be able to identify if an interface is a mapper or not.

The problem is that mappers are not annotated (the @Mapper annotation does not exist). We did this because we would like to build applications with no mybatis imports at all. So they way you select your mappers when using classic configuraiton like MapperScannerConfigurer or @MapperScan is by:

  • specifiying a base package
  • specifiying a marker interface
  • specifiying a marker annotation

So, my proposal is to use this convention: mappers are supposed to be interfaces held in a */mapper or */mappers package.

For any other configuration, use the @MapperScan annotation that lets you configure everything.

@mallim
Copy link
Contributor

mallim commented Apr 6, 2016

While waiting for this fix, is there anyway to disable the MapperScan from happening? Any example?

@emacarron
Copy link
Member Author

Yes. Add a @MapperScan to your main application class pointing to a dummy interface. That will register a MapperFactoryBean:

@SpringBootApplication
@MapperScan("dummy.package")
public class SampleMybatisApplication implements CommandLineRunner {

or create a MapperFactoryBean explicitly:

@Bean
MapperFactoryBean<Object> createMapper() {
  return new MapperFactoryBean<Object>();
}

If a MapperFactoryBean is detected autoscan is not done.

@mallim
Copy link
Contributor

mallim commented Apr 7, 2016

Thanks for the example, I think this is a good material to put in the docs. If not, people will have to come to this issue and read about this...

Anyway, this is what is working for my case:

@Configuration
@MapperScan("dummy")
public class MybatisConfig {

   @Bean
   public ActualMapper mapper(SqlSessionFactory sqlSessionFactory){
        SqlSessionTemplate sessionTemplate = new SqlSessionTemplate( sqlSessionFactory );
        return sessionTemplate.getMapper(ActualMapper.class);
   }
}

dummy package contains an interface:

public interface DummyMapper {
}

whereby my mybatis-config.xml has some mappers

hope this will help someone ...

@emacarron
Copy link
Member Author

Good to know! BTW, I am curious about this. Do you want to turn off scanning? if so, why?

@mallim
Copy link
Contributor

mallim commented Apr 7, 2016

I am using this way to avoid all interfaces to be registered as mybatis mappers even if they are not mappers. Actually, can we have a setting to turn off the @MapperScan ?

For example:

mybatis:
   scanning: true 

@emacarron
Copy link
Member Author

@mallim But... note that a mapper must be a bean in spring so it can be injected into any other bean. How are you registering your mapper? (or are you using the sqlSessionTemplate?)

@mallim
Copy link
Contributor

mallim commented Apr 7, 2016

Hi @emacarron

I registered all the mappers by using this way:

@Configuration
@MapperScan("dummy") // required since version 1.0.2
public class MybatisConfig {

   @Bean
   public ActualMapper1 mapper(SqlSessionFactory sqlSessionFactory){
        SqlSessionTemplate sessionTemplate = new SqlSessionTemplate( sqlSessionFactory );
        return sessionTemplate.getMapper(ActualMapper1.class);
   }

   @Bean
   public ActualMapper2 mapper(SqlSessionFactory sqlSessionFactory){
        SqlSessionTemplate sessionTemplate = new SqlSessionTemplate( sqlSessionFactory );
        return sessionTemplate.getMapper(ActualMapper2.class);
   }
}

whereby mybatis-config.xml has some mappers

spring-boot-starter works with this pattern since 1.0 👍

@emacarron
Copy link
Member Author

I see, but I would say you have too much boilerplate.

If you set the @MapperScan() with the package name (or pattern) where your mappers are this will work fine and you can remove that two @bean methods.

Can you check that?

@emacarron
Copy link
Member Author

BTW I just have updated master so autoscanning will only pick interfaces inside **/mapper or **/mappers package as a convention (over configration).

Details here: http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/

@kazuki43zoo I finally decided not to include "repository" to let people mix JPA and MyBatis in the same project.

Can you plese check the snapshot and let us know how it works?
repo: https://oss.sonatype.org/content/repositories/snapshots/

@kazuki43zoo
Copy link
Member

@emacarron

OK, i agree with your decision !!
I think this change should will be announced expressly on release note.

Thanks!

@emacarron
Copy link
Member Author

Sure. And thanks for your opinion!

@mallim
Copy link
Contributor

mallim commented Apr 8, 2016

@emacarron

My boilerplate way is still better than having this log appearing

2016-04-08 14:20:33.381  WARN 4828 --- [           main] o.m.s.mapper.ClassPathMapperScanner      : Skipping MapperFactoryBean with name 'XXXRepository' and 'XXXRepository' mapperInterface. Bean already defined with the same name!

And for trying to do this :-)

@MapperScan("pkg1,pkg2,pkg3,pkg4")

@emacarron
Copy link
Member Author

You can specify a pattern in basepackage. You may want to try that.
El 8 abr. 2016 8:41 a. m., "Ian Lim" notifications@github.com escribió:

@emacarron https://github.com/emacarron

My boilerplate way is still better than having this log appearing

2016-04-08 14:20:33.381 WARN 4828 --- [ main] o.m.s.mapper.ClassPathMapperScanner : Skipping MapperFactoryBean with name 'XXXRepository' and 'XXXRepository' mapperInterface. Bean already defined with the same name!

And for trying to do this :-)

@MapperScan("pkg1,pkg2,pkg3,pkg4")


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
#46 (comment)

@emacarron
Copy link
Member Author

I have recoded this to be more aligned with Spring @configuration that is based on annotations. So I have added a @Mapper marker annotation to the core so other DI frameworks can use it (spring, boot, cdi)

Thoughts?

@jeffgbutler
Copy link
Member

I think that's a good idea.

@mallim
Copy link
Contributor

mallim commented Apr 9, 2016

@emacarron

This is a very good idea 👍

@mnesarco
Copy link
Member

Hi @emacarron I didn't know about this Mapper annotation in advance so I have added one in CDI some time ago just before 1.0 release. Do you think we have to remove the cdi specific annotation and use just this?

@marwin1991
Copy link

marwin1991 commented Mar 1, 2021

I am using 3.5.6 And this still happens. I think MapperScan should have default value for annotationClass equal to org.apache.ibatis.annotations.Mapper.class

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

No branches or pull requests

6 participants