[英]Select Provider Mybatis Error: Parameter 'arg0' not found. Available parameters are [productAttributeDto, param1]
I am using Mybatis with the spring boot application.我将 Mybatis 与 spring 引导应用程序一起使用。 Where I used to generate MySql query using ProviderMethodResolver.
我曾经使用 ProviderMethodResolver 生成 MySql 查询。 My application supports mybatis annotation processor and XML processor.
我的应用程序支持 mybatis 注释处理器和 XML 处理器。
To achieve that I used this Mybatis configuration:为了实现这一点,我使用了这个 Mybatis 配置:
In appication.properties file在 appication.properties 文件中
mybatis.mapper-locations=classpath*:/repository/**/*Repository.xml
and a MybatisConfiguration.java和一个 MybatisConfiguration.java
@Configuration
@EnableTransactionManagement
public class MybatisConfiguration {
@Bean
ConfigurationCustomizer mybatisConfigurationCustomizer() {
return new ConfigurationCustomizer() {
@Override
public void customize(org.apache.ibatis.session.Configuration configuration) {
configuration.setMapUnderscoreToCamelCase(true);
configuration.setCacheEnabled(true);
}
};
}
}
With above configuration, everything( @Select, @Insert, @ResultMap
) seems working fine except implementation of @SelectProvider
.使用上述配置,除了
@SelectProvider
的实现之外,一切( @Select, @Insert, @ResultMap
)似乎工作正常。
SelectProvider Implemetation is SelectProvider 实现是
VariantRepository.java VariantRepository.java
@Mapper
public interface VariantRepository {
@SelectProvider(type = VariantSqlProvider.class, method = "getProductAttribute")
VariantDto findByProductAttribute(@Param("productAttributeDto") ProductAttributeDto productAttributeDto);
}
I am using
org.apache.ibatis.annotations.Param
我正在使用
org.apache.ibatis.annotations.Param
ProductAttributeDto.java产品属性Dto.java
@Data
public class ProductAttributeDto {
private Integer productId;
Map<String, String> attributes;
}
VariantSqlProvider.class VariantSqlProvider.class
public class VariantSqlProvider implements ProviderMethodResolver {
@SuppressWarnings("unused")
public static String getProductAttribute(final ProductAttributeDto productAttributeDto) {
return new SQL() {{
SELECT("*");
FROM("ec_product_variant AS pv");
if (Objects.nonNull(productAttributeDto.getAttributes())) {
for (Entry<String, String> entry : productAttributeDto.getAttributes().entrySet()) {
if(Objects.nonNull(entry.getValue())) {
INNER_JOIN(
new StringBuilder("ec_attributes AS ")
.append(entry.getKey())
.append(" ON ")
.append(entry.getKey()).append(".id = pv.").append(entry.getKey())
.append(" AND ")
.append(entry.getKey()).append(".value=#{productAttributeDto.attributes.").append(entry.getKey())
.append("}").toString()
);
} else {
WHERE("pv." + entry.getKey() + " IS NULL");
}
}
}
if(Objects.nonNull(productAttributeDto.getProductId())) {
WHERE("pv.product_id = #{productAttributeDto.productId}");
}
}}.toString();
}
}
When I invoke the findByProductAttribute
method, I get an error like this当我调用
findByProductAttribute
方法时,我收到这样的错误
org.apache.juli.logging.DirectJDKLog: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.builder.BuilderException: Error invoking SqlProvider method 'public static java.lang.String com.ecommerce.app.repository.product.sqlprovider.VariantSqlProvider.getProductAttribute(com.ecommerce.app.model.product.ProductAttributeDto)' with specify parameter 'class org.apache.ibatis.binding.MapperMethod$ParamMap'. Cause: org.apache.ibatis.binding.BindingException: Parameter 'arg0' not found. Available parameters are [productAttributeDto, param1]] with root cause
org.apache.ibatis.binding.BindingException: Parameter 'arg0' not found. Available parameters are [productAttributeDto, param1]
at org.apache.ibatis.binding.MapperMethod$ParamMap.get(MapperMethod.java:212)
at org.apache.ibatis.builder.annotation.ProviderSqlSource.extractProviderMethodArguments(ProviderSqlSource.java:223)
The SQL query I am expecting to generate is:我期望生成的 SQL 查询是:
SELECT *
FROM ec_product_variant AS pv
INNER JOIN ec_attributes AS color ON color.id = pv.color AND color.value=?
WHERE (pv.size IS NULL AND pv.product_id = ?)
The query is based on the attributes key-value pair in productAttributeDto
该查询基于 productAttributeDto 中的属性键值对
Here mybatis is looking for arg0 instead of productAttributeDto.这里 mybatis 是在寻找 arg0 而不是 productAttributeDto。 Can anyone help on this.
任何人都可以帮助解决这个问题。 What am I doing wrong here?
我在这里做错了什么? Thanks in advance.
提前致谢。
The error is caused by the parameter name mismatch between the mapper method and the provider method.该错误是由于mapper方法和provider方法的参数名称不匹配造成的。
@Param
annotation ie productAttributeDto
.@Param
注释指定,即productAttributeDto
。arg0
is used.arg0
。 These names must match.这些名称必须匹配。
There are two solutions.有两种解决方案。
@Param
annotation on the provider method parameter.@Param
注释。-parameters
compiler option enabled.-parameters
编译器选项的情况下构建您的应用程序。 The solution 1 is pretty straightforward.解决方案 1 非常简单。
public static String getProductAttribute(
@Param("productAttributeDto") final ProductAttributeDto productAttributeDto) {
The solution 2 depends on how you build your application.解决方案 2 取决于您如何构建应用程序。
If you use Maven, you may need to configure maven-compiler-plugin in the pom.xml.如果使用Maven,可能需要在pom.xml中配置maven-compiler-plugin。 eg
例如
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
When using IDE, you might need to configure the build setting.使用 IDE 时,您可能需要配置构建设置。
This way, MyBatis can retrieve the parameter name from the method signature, so you don't need to use @Param
annotation (you can still use @Param
if you want, though).这样,MyBatis 可以从方法签名中检索参数名称,因此您不需要使用
@Param
注解(不过,如果需要,您仍然可以使用@Param
)。
As a result, the mapper method can be simpler...结果,mapper方法可以更简单......
@SelectProvider(type = VariantSqlProvider.class, method = "getProductAttribute")
VariantDto findByProductAttribute(ProductAttributeDto productAttributeDto);
...and the provider method in your question should work as-is. ...并且您问题中的提供者方法应该按原样工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.