emacarron / mybatis

Automatically exported from code.google.com/p/mybatis
0 stars 0 forks source link

Constructor of ProviderSqlSource should throw exception if no matching method is found #148

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
MyBatis Version 3.0.2

The constructor of ProviderSqlSource doesn't throw an exception if the 
specified (searched for) method is not found in provider object. An exception 
is only thrown once the method that invokes the ProviderSqlSource  instance is 
called. 

I think an exception thrown at initialization/startup would be much more 
desirable.

Solution would be:

[code]
public ProviderSqlSource(Configuration config, Object provider) {
    try {
      this.sqlSourceParser = new SqlSourceBuilder(config);
      this.providerType = (Class) provider.getClass().getMethod("type").invoke(provider);
      String providerMethod = (String) provider.getClass().getMethod("method").invoke(provider);

      for (Method m : providerType.getMethods()) {
        if (providerMethod.equals(m.getName())) {
          if (m.getParameterTypes().length < 2
              && m.getReturnType() == String.class) {
            this.providerMethod = m;
            this.providerTakesParameterObject = m.getParameterTypes().length == 1;
          }
        }
      }
    } catch (Exception e) {
      throw new BuilderException("Error creating SqlSource for SqlProvider.  Cause: " + e, e);
    }
    if (this.providerMethod == null) {
        throw new BuilderException("Error creating SqlSource for SqlProvider. Method '" + 
                                    provider.getClass().getName() + "." + providerMethod + "' not found.");
    }
}
[/code]

Original issue reported on code.google.com by mulons...@gmail.com on 21 Oct 2010 at 6:24

GoogleCodeExporter commented 9 years ago
Thanks. 

It is indeeed very difficult to understand what the problem exactly is at the 
time we get this late exception (see below). Having an exception thrown before 
would lead to huge gain in debug time.

Also I have a question about this :

[code]
if (m.getParameterTypes().length < 2 && m.getReturnType() == String.class)
[/code]

Why cannot we have more than 1 parameter in the SqlProvider methods ??

Seems a undeeded limitation to me... (bug ?)

Best regards,
Jeremie

org.mybatis.spring.MyBatisSystemException: nested exception is 
org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: java.lang.NullPointerException
### The error may exist in com.TheMapper.java (best guess)
### The error may involve com.TheMapper.selectJoinStringExtendedBuilder
### The error occurred while executing a query
### Cause: java.lang.NullPointerException
    at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:73)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:346)
    at $Proxy21.selectList(Unknown Source)
    at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:189)
    at org.apache.ibatis.binding.MapperMethod.executeForList(MapperMethod.java:85)
    at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:65)
    at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:38)
    at $Proxy23.selectJoinStringExtendedBuilder(Unknown Source)
    at test2.Main.main(Main.java:267)
Caused by: org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: java.lang.NullPointerException
### The error may exist in com.TheMapper.java (best guess)
### The error may involve com.TheMapper.selectJoinStringExtendedBuilder
### The error occurred while executing a query
### Cause: java.lang.NullPointerException
    at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:8)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:77)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:69)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:338)
    ... 7 more
Caused by: java.lang.NullPointerException
    at org.apache.ibatis.builder.annotation.ProviderSqlSource.createSqlSource(ProviderSqlSource.java:54)
    at org.apache.ibatis.builder.annotation.ProviderSqlSource.getBoundSql(ProviderSqlSource.java:39)
    at org.apache.ibatis.mapping.MappedStatement.getBoundSql(MappedStatement.java:198)
    at org.apache.ibatis.executor.BaseExecutor.createCacheKey(BaseExecutor.java:115)
    at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:90)
    at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:72)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:75)
    ... 13 more

Original comment by jeremie....@gmail.com on 2 Feb 2011 at 10:20

GoogleCodeExporter commented 9 years ago
Thanks both! Fixed in r3620.

Original comment by eduardo.macarron on 3 Feb 2011 at 7:47

GoogleCodeExporter commented 9 years ago

Original comment by eduardo.macarron on 3 Mar 2012 at 9:11