英文:
Ambiguous method overloading for method de.hybris.platform.tx.DefaultTransaction#execute
问题
我们有一个调用Groovy脚本的定时任务。脚本的目标是根据多个条件更改产品属性的值。当我们运行这个定时任务,特别是Groovy脚本时,会出现以下错误。我还插入了接收到错误的Groovy脚本。我不记得这个问题是什么时候发生的,因为去年第四季度它还在工作。
错误:
脚本执行失败 [原因:java.util.concurrent.ExecutionException: groovy.lang.GroovyRuntimeException: Ambiguous method overloading for method de.hybris.platform.tx.DefaultTransaction#execute.
无法解析要为 [class UpdateWorker$_call_closure1] 调用的方法,因为在以下原型之间存在重叠:
[interface de.hybris.platform.tx.TransactionBody]
[interface de.hybris.platform.tx.TransactionBody$GenericTransactionBody]]
Groovy脚本:
import de.hybris.platform.servicelayer.model.ModelService
import de.hybris.platform.servicelayer.i18n.CommonI18NService
import de.hybris.platform.servicelayer.search.FlexibleSearchQuery
import java.util.stream.Collectors
import de.hybris.platform.core.model.enumeration.EnumerationValueModel
import com.SubstitutionModel
import de.hybris.platform.tx.Transaction
import groovy.time.TimeCategory
import groovy.time.TimeDuration
import java.util.Date
import com.google.common.collect.ImmutableSet
import com.google.common.collect.ImmutableMap
import de.hybris.platform.servicelayer.interceptor.impl.InterceptorExecutionPolicy
import de.hybris.platform.servicelayer.session.SessionExecutionBody
import de.hybris.platform.servicelayer.interceptor.impl.InterceptorExecutionPolicy.InterceptorType
import java.util.List
import java.util.concurrent.Callable
import de.hybris.platform.core.Registry
import java.util.concurrent.Executors
import de.hybris.platform.core.TenantAwareThreadFactory
import org.apache.log4j.Logger
import de.hybris.platform.servicelayer.session.SessionService
import de.hybris.platform.catalog.CatalogVersionService
import de.hybris.platform.servicelayer.search.impl.DefaultFlexibleSearchService
def COMMIT_PACE = 1000
def TOTAL_THREADS = 10
def log = Logger.getLogger('updateProductSubstitutionScript');
def query = /select distinct {p.pk} from {Product as p JOIN CatalogVersion as cv ON {p.catalogVersion} = {cv.PK}} where ({p.triggerSubstitutionCronjob} = 1 OR {p.substitutionIndicator} IS NULL OR {p.substitutionCode} IS NULL) and {cv.version} = 'Online'/
class UpdateWorker implements Callable {
// 产品替代枚举
def subCodeNoEntry = /0/
def subCodeOneEntry = /1/
def subCodeMoreEntriesNoConditionalNotes = /2/
def subCodeMoreEntriesWithConditionalNotes = /3/
def subIndicatorBoth = /B/
def subIndicatorForward = /F/
def subIndicatorPrevious = /P/
def subIndicatorEmpty = /N/
def catalogVersionService
def newCv
List lines
def privateLogger
def sessionService
def modelService
def flexibleSearchService
def params = ImmutableMap.of(InterceptorExecutionPolicy.DISABLED_UNIQUE_ATTRIBUTE_VALIDATOR_FOR_ITEM_TYPES, ImmutableSet.of('Product','Substitution'));
public UpdateWorker(List linesToProcess, Logger logger, SessionService sessionService, ModelService modelService, CatalogVersionService catalogVersionService, DefaultFlexibleSearchService flexibleSearchService){
lines = linesToProcess
privateLogger = logger
this.sessionService = sessionService
this.modelService = modelService
this.catalogVersionService = catalogVersionService
this.flexibleSearchService = flexibleSearchService
}
def String call() {
def startThread = new Date()
privateLogger.info('IsNested transaction: ' + Transaction.current().isNested())
Transaction.current().execute(
{
lines.each { line ->
sessionService.executeInLocalViewWithParams(params, new SessionExecutionBody(){ public void executeWithoutResult(){
def queryForSubstitution = /select distinct {s.pk} from {Substitution as s} where ({s.partForSubstitutionCode} = ?productPk or {s.skuReplacementCode} = ?productPk) and {s.partForSubstitutionCode} is not null and {s.skuReplacementCode} is not null/
def productPk = line.getCode();
def queryParams = [:];
queryParams.put('productPk', productPk);
final FlexibleSearchQuery fsQuery = new FlexibleSearchQuery(queryForSubstitution, queryParams);
def substitutions = flexibleSearchService.search(fsQuery).getResult();
if(substitutions.size() == 0)
{
line.setSubstitutionCode(subCodeNoEntry);
line.setSubstitutionIndicator(subIndicatorEmpty);
}
else{
def subFromList = [];
def subToList = [];
//Split into 2 list
for(SubstitutionModel substitution : substitutions)
{
//These fields are mandatories during hotfolder process
//Anyway are not mandatories in hybris sistem, this null check avoid to abort cronjob
if(substitution.getPartForSubstitutionCode() != null && substitution.getSkuReplacementCode() != null)
{
if(substitution.getPartForSubstitutionCode() == productPk) {
subFromList.add(substitution)
} else {
subToList.add(substitution)
}
}
}
//Calculate substitution code
def substitutionCode;
if(subFromList.size() == 0){
substitutionCode = subCodeNoEntry
}
else if(subFromList.size() == 1){
if(subFromList.get(0).getConditionalNotes() != null && !subFromList.get(0).getConditionalNotes().isEmpty())
{
substitutionCode = subCodeMoreEntriesWithConditionalNotes
}
else{
substitutionCode = subCodeOneEntry
}
}
else{
substitutionCode = subCodeMoreEntriesNoConditionalNotes
for(SubstitutionModel substitution : substitutions)
{
if(substitution.getConditionalNotes() != null && !substitution.getConditionalNotes().isEmpty()){
substitutionCode = subCodeMoreEntriesWithConditionalNotes
break
}
}
}
line.setSubstitutionCode(substitutionCode)
//Calculate substitution indicator
def substitutionIndicator;
if(subFromList.size() >
英文:
We have a cronjob that is calling a groovy script. The goal of the script is to change the value of a product property depending on several conditions. When we run the cronjob, specifically the groovy script, we get below error. I also inserted the groovy script that is receiving the error. I don't remember when this issue occurred because it was working last year 4th quarter.
Error:
Script execution has failed [reason: java.util.concurrent.ExecutionException: groovy.lang.GroovyRuntimeException: Ambiguous method overloading for method de.hybris.platform.tx.DefaultTransaction#execute.
Cannot resolve which method to invoke for [class UpdateWorker$_call_closure1] due to overlapping prototypes between:
[interface de.hybris.platform.tx.TransactionBody]
[interface de.hybris.platform.tx.TransactionBody$GenericTransactionBody]]
Groovy script:
import de.hybris.platform.servicelayer.model.ModelService
import de.hybris.platform.servicelayer.i18n.CommonI18NService
import de.hybris.platform.servicelayer.search.FlexibleSearchQuery
import java.util.stream.Collectors
import de.hybris.platform.core.model.enumeration.EnumerationValueModel
import com.SubstitutionModel
import de.hybris.platform.tx.Transaction
import groovy.time.TimeCategory
import groovy.time.TimeDuration
import java.util.Date
import com.google.common.collect.ImmutableSet
import com.google.common.collect.ImmutableMap
import de.hybris.platform.servicelayer.interceptor.impl.InterceptorExecutionPolicy
import de.hybris.platform.servicelayer.session.SessionExecutionBody
import de.hybris.platform.servicelayer.interceptor.impl.InterceptorExecutionPolicy.InterceptorType
import java.util.List
import java.util.concurrent.Callable
import de.hybris.platform.core.Registry
import java.util.concurrent.Executors
import de.hybris.platform.core.TenantAwareThreadFactory
import org.apache.log4j.Logger
import de.hybris.platform.servicelayer.session.SessionService
import de.hybris.platform.catalog.CatalogVersionService
import de.hybris.platform.servicelayer.search.impl.DefaultFlexibleSearchService
def COMMIT_PACE = 1000
def TOTAL_THREADS = 10
def log = Logger.getLogger('updateProductSubstitutionScript');
def query = /select distinct {p.pk} from {Product as p JOIN CatalogVersion as cv ON {p.catalogVersion} = {cv.PK}} where ({p.triggerSubstitutionCronjob} = 1 OR {p.substitutionIndicator} IS NULL OR {p.substitutionCode} IS NULL) and {cv.version} = 'Online'/
class UpdateWorker implements Callable {
// Product substitution enum
def subCodeNoEntry = /0/
def subCodeOneEntry = /1/
def subCodeMoreEntriesNoConditionalNotes = /2/
def subCodeMoreEntriesWithConditionalNotes = /3/
def subIndicatorBoth = /B/
def subIndicatorForward = /F/
def subIndicatorPrevious = /P/
def subIndicatorEmpty = /N/
def catalogVersionService
def newCv
List lines
def privateLogger
def sessionService
def modelService
def flexibleSearchService
def params = ImmutableMap.of(InterceptorExecutionPolicy.DISABLED_UNIQUE_ATTRIBUTE_VALIDATOR_FOR_ITEM_TYPES, ImmutableSet.of('Product','Substitution'));
public UpdateWorker(List linesToProcess, Logger logger, SessionService sessionService, ModelService modelService, CatalogVersionService catalogVersionService, DefaultFlexibleSearchService flexibleSearchService){
lines = linesToProcess
privateLogger = logger
this.sessionService = sessionService
this.modelService = modelService
this.catalogVersionService = catalogVersionService
this.flexibleSearchService = flexibleSearchService
}
def String call() {
def startThread = new Date()
privateLogger.info('IsNested transaction: ' + Transaction.current().isNested())
Transaction.current().execute(
{
lines.each { line ->
sessionService.executeInLocalViewWithParams(params, new SessionExecutionBody(){ public void executeWithoutResult(){
def queryForSubstitution = /select distinct {s.pk} from {Substitution as s} where ({s.partForSubstitutionCode} = ?productPk or {s.skuReplacementCode} = ?productPk) and {s.partForSubstitutionCode} is not null and {s.skuReplacementCode} is not null/
def productPk = line.getCode();
def queryParams = [:];
queryParams.put('productPk', productPk);
final FlexibleSearchQuery fsQuery = new FlexibleSearchQuery(queryForSubstitution, queryParams);
def substitutions = flexibleSearchService.search(fsQuery).getResult();
if(substitutions.size() == 0)
{
line.setSubstitutionCode(subCodeNoEntry);
line.setSubstitutionIndicator(subIndicatorEmpty);
}
else{
def subFromList = [];
def subToList = [];
//Split into 2 list
for(SubstitutionModel substitution : substitutions)
{
//These fields are mandatories during hotfolder process
//Anyway are not mandatories in hybris sistem, this null check avoid to abort cronjob
if(substitution.getPartForSubstitutionCode() != null && substitution.getSkuReplacementCode() != null)
{
if(substitution.getPartForSubstitutionCode() == productPk) {
subFromList.add(substitution)
} else {
subToList.add(substitution)
}
}
}
//Calculate substitution code
def substitutionCode;
if(subFromList.size() == 0){
substitutionCode = subCodeNoEntry
}
else if(subFromList.size() == 1){
if(subFromList.get(0).getConditionalNotes() != null && !subFromList.get(0).getConditionalNotes().isEmpty())
{
substitutionCode = subCodeMoreEntriesWithConditionalNotes
}
else{
substitutionCode = subCodeOneEntry
}
}
else{
substitutionCode = subCodeMoreEntriesNoConditionalNotes
for(SubstitutionModel substitution : substitutions)
{
if(substitution.getConditionalNotes() != null && !substitution.getConditionalNotes().isEmpty()){
substitutionCode = subCodeMoreEntriesWithConditionalNotes
break
}
}
}
line.setSubstitutionCode(substitutionCode)
//Calculate substitution indicator
def substitutionIndicator;
if(subFromList.size() > 0 && subToList.size() > 0){
substitutionIndicator = subIndicatorBoth
}
else if (subFromList.size() > 0 && subToList.size() == 0){
substitutionIndicator = subIndicatorForward
}
else if (subFromList.size() == 0 && subToList.size() > 0){
substitutionIndicator = subIndicatorPrevious
}
line.setSubstitutionIndicator(substitutionIndicator)
}
line.setTriggerSubstitutionCronjob(false)
modelService.save(line)
}})
}
}
)
def stopThread = new Date()
def TimeDuration td = TimeCategory.minus( stopThread, startThread )
privateLogger.info('Sanitized ' + lines.size() + ' elements in' + td)
return 'Sanitized ' + lines.size() + ' elements in' + td
}
}
defaultFlexibleSearchService = spring.getBean('defaultFlexibleSearchService')
final FlexibleSearchQuery fsQuery = new FlexibleSearchQuery(query)
fsQuery.setStart(0)
fsQuery.setCount(COMMIT_PACE*TOTAL_THREADS)
threadFactory = new TenantAwareThreadFactory(Registry.currentTenant, Registry.currentTenant.activeSession)
executorService = Executors.newFixedThreadPool(TOTAL_THREADS,threadFactory)
boolean morelines = true
count = 0
def startMain = new Date()
//while(modelines && count<3){
while(morelines){
start = new Date()
result = flexibleSearchService.search(fsQuery)
if (result.getCount()==0){
log.info('No more lines to move')
morelines=false
}
else{
resultList = result.getResult()
List workers = new ArrayList();
resultsForWorker = resultList.collate(COMMIT_PACE)
resultsForWorker.each{
linesForWorker -> log.info('Lines to move for worker: ' + linesForWorker.size())
workers.add(new UpdateWorker(linesForWorker, log, sessionService, modelService, catalogVersionService, defaultFlexibleSearchService))
}
List durationsFuture = executorService.invokeAll(workers)
durationsFuture.each{ durationFuture ->
log.info('Retrieved worker duration: ' + durationFuture.get())
}
count++
}
modelService.detachAll();
}
def stopMain = new Date()
def TimeDuration overallTd = TimeCategory.minus( stopMain, startMain )
log.info('Overall sanitization process duration: ' + overallTd)
executorService.shutdown()
答案1
得分: 0
execute() method should have explicit type to be executed
和代码应该像这样。
def String call() {
def startThread = new Date()
privateLogger.info('IsNested transaction: ' + Transaction.current().isNested())
Transaction.current().execute({ TransactionBody txBody ->
lines.each { line ->
sessionService.executeInLocalViewWithParams(params, new SessionExecutionBody(){ public void executeWithoutResult(){
//Rest code should be as same
}
} as TransactionBody)
}
def stopThread = new Date()
def TimeDuration td = TimeCategory.minus(stopThread, startThread)
privateLogger.info('Sanitized ' + lines.size() + ' elements in ' + td)
return 'Sanitized ' + lines.size() + ' elements in ' + td
}
如果您需要进一步的帮助,请随时告诉我。
英文:
execute() method should have explicit type to be executed
and the code should be like this.
def String call() {
def startThread = new Date()
privateLogger.info('IsNested transaction: ' + Transaction.current().isNested())
Transaction.current().execute(
{ TransactionBody txBody ->
lines.each { line ->
sessionService.executeInLocalViewWithParams(params, new SessionExecutionBody(){ public void executeWithoutResult(){
//Rest code should be as same
}
as TransactionBody)
def stopThread = new Date()
def TimeDuration td = TimeCategory.minus( stopThread, startThread )
privateLogger.info('Sanitized ' + lines.size() + ' elements in' + td)
return 'Sanitized ' + lines.size() + ' elements in' + td
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论