org.apache.ibatis.reflection.ReflectionException: There is no setter for property named 'doBatchResult' in 'class java.lang.Class'

1,503 views
Skip to first unread message

Daniel Wilkerson

unread,
Apr 21, 2015, 4:10:52 PM4/21/15
to mybati...@googlegroups.com
UPDATE:

Sorry if this double posts. I sent this out via email earlier and never saw it show up on the forum; now resubmitting through the browser interface. I've since solved part of this issue, but am not completely out of the water.

I had to pass the mapper interface method a reference to the POJO type I was looking to use for the result (StagingManagement) to get rid of this error. The issue I'm having now is the result is not surfacing in the POJO. It comes back null. When I step through in the debugger, I can see it's getting set deep under the hood, but it's just not surfacing correctly.

            StagingManagement stagmag = new StagingManagement();
            stagmag = lmsSqlSession.selectOne("callEtlDoBatch", stagmag);
            System.out.println("<<Done>>");
            System.out.println(stagmag.getDoBatchResult());

import com.workplace.staging.somesystem.data.domain.StagingManagement;

public interface StagingManagementMapper {

        //public String callEtlDoBatch();
        public StagingManagement callEtlDoBatch(StagingManagement doBatchResult);
}

I'm struggling with the idea that calling a simple stored proc with a String return value is this difficult in MyBatis. Everything else has always worked well and be fairly easy to understand/deal with.

Any help would be greatly appreciated. There is definitely some things I'm not quite understanding with regard to MyBatis and stored procs.

<<<<<<<<<<<<<<<<< OLD POST >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Hi everyone. I'm trying to add in stored procedure calls to a MyBatis application we have and am able to get them to execute, however, when MyBatis tries to map the results back into the Pojo I have coded I get:
Caused by: org.apache.ibatis.reflection.ReflectionException: Could not set property 'doBatchResult' of 'class java.lang.Class' with value '

My code is below. I'd appreciate any help with this. The docs don't cover stored procs hardly at all and much of what I find in web searches show use cases that aren't like mine and I'm out of gas trying to figure this out; been stuck for a day and a half on this. The closest I could find was this blog: http://java.dzone.com/articles/ibatis-mybatis-working-stored, however, these examples in context to my code didn't work either. The code below shows a resultMap being used, but I've tried parameter maps, and just using resultType to let MyBatis figure it out, and more. None has worked so far.

It's pretty simple. I have one stored proc located on a Postgresql 9.1 machine that I need to call. It only has one out param that returns a long string with the results of the operation. That's it.

<<<<<<<<<<<<<<<<<<< MODEL POJO >>>>>>>>>>>>>>>>>>>>>>>>>>>
public class StagingManagement {

    private String doBatchResult;

    public String getDoBatchResult() {
        return doBatchResult;
    }

    public void setDoBatchResult(String doBatchResult) {
        this.doBatchResult = doBatchResult;
    }
}

<<<<<<<<<<<<<<<<<<< MAPPER INTERFACE >>>>>>>>>>>>>>>>>>>>>>>>>>>
package com.workplace.staging.somesystem.data.client;

import com.workplace.staging.somesystem.data.domain.StagingManagement;

public interface StagingManagementMapper {


        public StagingManagement callEtlDoBatch();
}

<<<<<<<<<<<<<<<<<<< MAPPER FILE >>>>>>>>>>>>>>>>>>>>>>>>>>>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.workplace.staging.somesystem.data.client.StagingManagementMapper">


    <resultMap id="ProcResultMap" type="com.workplace.staging.somesystem.data.domain.StagingManagement">
        <result column="result" jdbcType="VARCHAR" property="doBatchResult"/>
    </resultMap>

    <select id="callEtlDoBatch" useCache="false" resultMap="ProcResultMap" statementType="CALLABLE">
        { CALL staging.etl_do_batch(#{doBatchResult, mode=OUT, jdbcType=VARCHAR})}
    </select>
</mapper>

<<<<<<<<<<<<<<<<<<< EXCEPTION OUTPUT >>>>>>>>>>>>>>>>>>>>>>>>>>>
Batch ID 681 Complete.' Cause: org.apache.ibatis.reflection.ReflectionException: There is no setter for property named 'doBatchResult' in 'class java.lang.Class'
    at org.apache.ibatis.reflection.wrapper.BeanWrapper.setBeanProperty(BeanWrapper.java:175)
    at org.apache.ibatis.reflection.wrapper.BeanWrapper.set(BeanWrapper.java:57)
    at org.apache.ibatis.reflection.MetaObject.setValue(MetaObject.java:133)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleOutputParameters(DefaultResultSetHandler.java:117)
    at org.apache.ibatis.executor.statement.CallableStatementHandler.query(CallableStatementHandler.java:68)
    at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:73)
    at org.apache.ibatis.executor.BatchExecutor.doQuery(BatchExecutor.java:87)
    at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:267)
    at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:137)
    at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:96)
    at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:77)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:108)
    ... 7 more
Caused by: org.apache.ibatis.reflection.ReflectionException: There is no setter for property named 'doBatchResult' in 'class java.lang.Class'
    at org.apache.ibatis.reflection.Reflector.getSetInvoker(Reflector.java:372)
    at org.apache.ibatis.reflection.MetaClass.getSetInvoker(MetaClass.java:174)
    at org.apache.ibatis.reflection.wrapper.BeanWrapper.setBeanProperty(BeanWrapper.java:167)
    ... 18 more

Thanks,
Daniel

Jeff Butler

unread,
Apr 21, 2015, 5:51:03 PM4/21/15
to mybati...@googlegroups.com
This is the most common stored procedure issue by a mile :)

Your stored procedure appears to be using an OUT parameter, not returning a result set.  If this is the case, then <select> is not the proper MyBatis method to use because there is no result set and <select> always expects a result set.  We normally recommend using <update> in cases like this (even though there is no data changed, update is just a method that doesn't expect a result set).

Your Java mapper method would look like this:

public void callEtlDoBatch(StagingManagement doBatchResult);

And you don't need the result map because there is no result set.  The StagingManagement object should be updated after the call.

Jeff Butler


--
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...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Daniel Wilkerson

unread,
Apr 23, 2015, 2:55:51 PM4/23/15
to mybati...@googlegroups.com
Awesome! Thanks for the help and clarification Jeff. I sincerely appreciate it. :)

I've been a fan of MyBatis and MyBatis generator for quite some time. It has served me well many times for data access work. I was surprised when I started stumbling on this: hadn't had to do stored proc work with MB until now.

Ok that makes sense. Certainly sounds way easier than what I was trying…lol.

So what would my mapper.xml file look like (in terms of the correct attributes for the update tag)? I see the parameterMaps are a no-no now seeing as they're deprecated. Would I just use resultType instead of resultMap then…or perhaps not at all? Lastly, how would I get the value of the result returned from the call if the mapper's interface method is return type void?


Daniel

Jeff Butler

unread,
Apr 23, 2015, 3:58:13 PM4/23/15
to mybati...@googlegroups.com
<update> doesn't need anything besides an id and statementType="CALLABLE".  It's kind of weird, but the new value will be placed into the object you pass as a parameter.  It is not returned from the mapper method, it is just updated in the parameter object.

Every time I think I will finally write the definitive guide on how to call stored procedures in MyBatis, something else comes along and I ultimately forget about it.  But..I wrote a comprehensive set of tests that demonstrate most of the possibilities a few years ago.  You can see them here:


These tests show everything except using a refcursor as an out parameter.  If you need to see how that works, then the tests are here:


Jeff Butler



--
Reply all
Reply to author
Forward
0 new messages