MyBatis version
3.5.13
Database vendor and version
PostgreSQL 16.1
Test case or example project
https://github.com/OverDrone/mybatis-param
Steps to reproduce
record MainRecord(String value) {}
@Mapper
interface MainMapper {
@Select("SELECT #{rec.value}")
String test(MainRecord rec);
}
public void test() {
mapper.test(new MainRecord("123"));
}
Expected result
123
Actual result
org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'rec' in 'class mybatis.MainRecord'
As you can see in my test project following code works:
@Select("SELECT #{val}")
String test1(String val);
@Select("SELECT #{rec.value}")
String test3(MainRecord rec, String val);
There was already a bug reported before #1237
but it mentioned only simple objects, test1 in my example.
Same problem with vanilla classes as well, test4, test5 in my example:
public class MainClass {
private final String value;
public MainClass(final String value) {
super();
this.value = value;
}
public String getValue() {
return value;
}
}
@Select("SELECT #{cl.value}")
String test4(MainClass cl);
@Select("SELECT #{cl.value}")
String test5(MainClass cl, String val);
if it is so important to keep this feature by default (when you specify object fields directly without prefixing with parameter name if this parameter is the only one) then at least give an option to disable it.
useActualParamName enabled by default and doesn't help.
Why is it important? It's very refactor unfriendly. Say I have a query couple of screens with lots of mentions of ${request.field...}, then I decide that I don't need all other method parameters, keep only one parameter, then all of a sudden I need to go through sql and replace ${request.field...} to {field...}. Another day I decide to bring back some parameter and then whole story again replacing back {field...} to ${request.field...}, but in this case I can't even find all parameter names automatically because they don't have a common prefix.
Workaround is to specify @Param("request") MainRecord rec, but this makes code messy, because you need to add comment why in this particular case you use Param annotation.
MyBatis version
3.5.13
Database vendor and version
PostgreSQL 16.1
Test case or example project
https://github.com/OverDrone/mybatis-param
Steps to reproduce
Expected result
123
Actual result
org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'rec' in 'class mybatis.MainRecord'As you can see in my test project following code works:
There was already a bug reported before #1237
but it mentioned only simple objects, test1 in my example.
Same problem with vanilla classes as well, test4, test5 in my example:
if it is so important to keep this feature by default (when you specify object fields directly without prefixing with parameter name if this parameter is the only one) then at least give an option to disable it.
useActualParamName enabled by default and doesn't help.
Why is it important? It's very refactor unfriendly. Say I have a query couple of screens with lots of mentions of ${request.field...}, then I decide that I don't need all other method parameters, keep only one parameter, then all of a sudden I need to go through sql and replace ${request.field...} to {field...}. Another day I decide to bring back some parameter and then whole story again replacing back {field...} to ${request.field...}, but in this case I can't even find all parameter names automatically because they don't have a common prefix.
Workaround is to specify
@Param("request") MainRecord rec, but this makes code messy, because you need to add comment why in this particular case you use Param annotation.