"No setter found for the keyProperty 'id'" error when moving from 3.4.1 to 3.4.2

82 views
Skip to first unread message

zachv

unread,
Jun 8, 2017, 10:21:33 AM6/8/17
to mybatis-user
Hi

Between version 3.4.1 and 3.4.2 (and higher) I get the following error:

Caused by: org.apache.ibatis.executor.ExecutorException: Error getting generated key or setting result to parameter object. Cause: org.apache.ibatis.executor.ExecutorException: No setter found for the keyProperty 'id' in java.lang.Class.
    at org
.apache.ibatis.executor.keygen.Jdbc3KeyGenerator.processBatch(Jdbc3KeyGenerator.java:82)
    at org
.apache.ibatis.executor.keygen.Jdbc3KeyGenerator.processAfter(Jdbc3KeyGenerator.java:56)
    at org
.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:50)
    at org
.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:74)
    at org
.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:50)
    at org
.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117)
    at org
.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76)
    at org
.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:198)
   
... 4 more
Caused by: org.apache.ibatis.executor.ExecutorException: No setter found for the keyProperty 'id' in java.lang.Class.
    at org
.apache.ibatis.executor.keygen.Jdbc3KeyGenerator.populateKeys(Jdbc3KeyGenerator.java:131)
    at org
.apache.ibatis.executor.keygen.Jdbc3KeyGenerator.processBatch(Jdbc3KeyGenerator.java:78)
   
... 11 more


I have this in my mybatis config:
    <setting name="useGeneratedKeys" value="true" />

And I am doing a simple annotation based update statement:

 
   public interface BasicMapper {
       
@Update("update some_table set some_value = 'blah' where some_id = 1")
       
public int updateSomeValue();
   
}



This was working before, but only works if I either set the global useGeneratedKeys=false or add the following per statement: @Options(useGeneratedKeys=false). Changing either would result in wide ranging affects on our code base.

I wonder about whether this default keyProperty of "id" makes sense in MappedAnnotationBuilder, but that is not the the change that caused the problem.

See this commit in 3.4.2:
https://github.com/mybatis/mybatis-3/commit/7164f15e033c3f658df8004517f157dcdab51776
    
 
 private void populateKeys(ResultSet rs, MetaObject metaParam, String[] keyProperties, TypeHandler<?>[] typeHandlers) throws SQLException {
   
for (int i = 0; i < keyProperties.length; i++) {
     
String property = keyProperties[i];
     
if (!metaParam.hasSetter(property)) {
       
throw new ExecutorException("No setter found for the keyProperty '" + property + "' in " + metaParam.getOriginalObject().getClass().getName() + ".");
     
}
     
TypeHandler<?> th = typeHandlers[i];
     
if (th != null) {
       
Object value = th.getResult(rs, i + 1);
        metaParam
.setValue(property, value);
     
}
   
}
 
}


Which was as follows in 3.4.1:

  private void populateKeys(ResultSet rs, MetaObject metaParam, String[] keyProperties, TypeHandler<?>[] typeHandlers) throws SQLException {
   
for (int i = 0; i < keyProperties.length; i++) {
     
TypeHandler<?> th = typeHandlers[i];
     
if (th != null) {
       
Object value = th.getResult(rs, i + 1);
        metaParam
.setValue(keyProperties[i], value);
     
}
   
}
 
}



While the default keyProperty of "id" was present it would never execute getResultSet because in my case type handler is null.

In my limited understanding I see 2 options:
1. Drop the default keyProperty value (might have significant affect for backwards compatibility I would guess, but can't see why it is there)
2. Or change the above to do the key property check after the type handler check:

  private void populateKeys(ResultSet rs, MetaObject metaParam, String[] keyProperties, TypeHandler<?>[] typeHandlers) throws SQLException {
   
for (int i = 0; i < keyProperties.length; i++) {
     
TypeHandler<?> th = typeHandlers[i];
     
if (th != null) {
       
String property = keyProperties[i];
       
if (!metaParam.hasSetter(property)) {
         
throw new ExecutorException("No setter found for the keyProperty '" + property + "' in " + metaParam.getOriginalObject().getClass().getName() + ".");
       
}
       
Object value = th.getResult(rs, i + 1);
        metaParam
.setValue(property, value);
     
}
   
}
 
}


Any of those changes make sense?

thanks

Iwao AVE!

unread,
Jun 8, 2017, 2:09:22 PM6/8/17
to mybatis-user
Hi,

The database is PostgreSQL, right?
We track the issue with the following ticket.

Thank you very much for the detailed info!

Regards,
Iwao

--
You received this message because you are subscribed to the Google Groups "mybatis-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mybatis-user+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

zachv

unread,
Jun 9, 2017, 12:09:03 AM6/9/17
to mybatis-user
It is postgres.

Thank you for your work on this great tool... :)
Reply all
Reply to author
Forward
0 new messages