模糊的方法重载,用于方法de.hybris.platform.tx.DefaultTransaction#execute。

huangapple go评论53阅读模式
英文:

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
}
}

huangapple
  • 本文由 发表于 2023年5月29日 13:38:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76354899.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定