Erro ao buscar produtos... Erros


#1

Bom, indo direto ao assunto.
Tenho uma lista de produtos que contém aproximadamente 170 produtos. O problema quando vo realizar a busca ele simplesmente vai executando até da estouro de memória. Foi identificado que isso é causado por produtos específicos, mas que não possuem características em comum.
Problema eh q contendo 170 produtos ou apenas 1 produto numa lista de preço X. Quando eu mando buscar nessa lista de preço ele “trava” se existir um certo produto, mas sei que isso nao eh devido explicitamente a produto específico.
Já olhei banco de dados, os ids… entre outros mas nao achei nda de “anormal”.

Queria entender o processo de busca, ou saber qual a classe q ele executa para tentar fzer alguma alteração.

Se algué souber pelo menos qual classe que ele executa essa busca. Sei que ele deve implementar algo do tipo :
Sabendo que:
ad_column_id, columnname,tablename
2064, M_Product_ID, M_ProductPrice

	MLookup Product = MLookupFactory.get(Env.getCtx(), m_WindowNo, 0,2064, DisplayType.Search);
	finProduct = new VLookup("M_Product_ID", true, false, true, ProjectL);
	finProduct.addVetoableChangeListener(this);

Desde já agradeço. Será que algum erro na classe org.compiere.apps.search.InfoProduct
Qualquer modo vo continuar rastreando mas aguardo alguma “luz”

[]'s

Fernando


#2

Bom, dps de algumas horas… descobri que , é executado o org.compiere.apps.form.search.InfoProduct, que chama o Info… e por ae vai

SQL

SELECT p.M_Product_ID, p.Discontinued, p.Value, p.Name, bomQtyAvailable(p.M_Product_ID,1000001,0) AS QtyAvailable, bomPriceList(p.M_Product_ID, pr.M_PriceList_Version_ID) AS PriceList,

bomPriceStd(p.M_Product_ID, pr.M_PriceList_Version_ID) AS PriceStd, bomQtyOnHand(p.M_Product_ID,1000001,0)

AS QtyOnHand, bomQtyReserved(p.M_Product_ID,1000001,0) AS QtyReserved, bomQtyOrdered(p.M_Product_ID,1000001,0)

AS QtyOrdered, bomPriceStd(p.M_Product_ID, pr.M_PriceList_Version_ID)-bomPriceLimit(p.M_Product_ID, pr.M_PriceList_Version_ID)

AS Margin, bp.Name, bomPriceLimit(p.M_Product_ID, pr.M_PriceList_Version_ID) AS PriceLimit, pa.IsInstanceAttribute

FROM M_Product p LEFT OUTER JOIN M_ProductPrice pr ON (p.M_Product_ID=pr.M_Product_ID AND pr.IsActive=‘Y’) LEFT OUTER JOIN

M_AttributeSet pa ON (p.M_AttributeSet_ID=pa.M_AttributeSet_ID) LEFT OUTER JOIN M_Product_PO ppo ON (p.M_Product_ID=ppo.M_Product_ID)

LEFT OUTER JOIN C_BPartner bp ON (ppo.C_BPartner_ID=bp.C_BPartner_ID) WHERE p.IsActive=‘Y’ AND p.IsSummary=‘N’ AND p.IsSummary=‘N’

AND p.IsActive=‘Y’ AND pr.M_PriceList_Version_ID=1000000 AND p.AD_Client_ID IN(0,1000000) AND p.AD_Org_ID IN(0,1000000)

AND p.M_Product_ID NOT IN ( SELECT Record_ID FROM AD_Private_Access WHERE AD_Table_ID = 208 AND AD_User_ID <> 100 AND IsActive = ‘Y’ )

AND pa.M_AttributeSet_ID NOT IN ( SELECT Record_ID FROM AD_Private_Access WHERE AD_Table_ID = 560 AND AD_User_ID <> 100

AND IsActive = ‘Y’ ) AND bp.C_BPartner_ID NOT IN ( SELECT Record_ID FROM AD_Private_Access WHERE AD_Table_ID = 291

AND AD_User_ID <> 100 AND IsActive = ‘Y’ ) ORDER BY QtyAvailable DESC, Margin DESC

Este é o SQL executado que trava o adempiere, o problema não se encontra no adempiere, pois, através do debug, descobri q trava quando vai pro banco através do preparedstatement. O q muda é apenas a versão da lista de preço (que tbm não é influente- acredito eu).

O erro talvez se encontre ns funçoes que ele chama,bomQtyAvailable, bomPriceList, bomPriceList, bomQtyReserved, bomQtyOnHand, bomQty, entre outras. Essas funções necessitam do pljava para executar no banco.

Elas podem ser visualizadas no pacote org.compiere.sqlj.Product… ele por acaso chama essas funções aqui implementas?

Ai olhando os bugs fixados na pagina do adempiere temos:

Fix bug 1649453 - bomQtyAvailable sqlj function throw ArithmeticException (Hengsin)

Fix bug 1650898 - Production Run doesn’t complete (Hengsin)

Alguma luz? ^^


#3

Continuando

Com um pouco mais de testes:

Descobri que o erro se encontra na funcao bomQty.

Pois ele executa SQL:

SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType FROM M_Product_BOM b, M_Product p WHERE b.M_ProductBOM_ID=p.M_Product_ID AND b.M_Product_ID=?

Os produtos que dão erro possuem b.M_Product_ID=b.M_ProductBOM_ID, ou seja, o produto possui ele próprio na lista de materiais

Portanto o erro vem do loop q entra , devido a “coincidencia”, logo, chamando a função sempre com os mesmos parâmetros

classe org.compiere.sqlj.Product
function bomQty

else if (isBOM) // Another BOM
{

			productQuantity = bomQty (M_ProductBOM_ID, M_Warehouse_ID, p_M_Locator_ID, p_what);
			//	How much can we make overall
			if (productQuantity.compareTo(quantity) < 0)
				quantity = productQuantity;
		}

e pelo fato isBom (Bill of Materials- Possuir lista de materiais) ser verdadeiro. Entra no loop infinito.

Logo, o adempiere nao deveria permitir que um produto tivesse na sua lista de materiais ele próprio.

Resolvido ^^

Agora so colocar uma validacao nao permitindo que um material possua ele próprio na lista de materiais (prefiro eu, através do beforeSave), o que acham ?


#4

Pra mim isso é um bug, seria bom que você reportasse para correção.

Prefiro modificar esse if acrescentando algo do tipo:

[code]else if (isBOM and ProdutoID != BOM_Produto_ID) // Another BOM. Não executa se a referência for para o próprio
{

productQuantity = bomQty (M_ProductBOM_ID, M_Warehouse_ID, p_M_Locator_ID, p_what);
// How much can we make overall
if (productQuantity.compareTo(quantity) < 0)
quantity = productQuantity;
}[/code]

Se o problema é execução em loop infinito, isso evitaria chamar novamente o método para o mesmo produto.

Obs.: Verifique duas vezes se o que sugeri não interfere em mais coisas. Não conheço nem o funcionamento do Adempiere direito ainda, a nível de código então…

Abraço


#5

importante, se vc realmente for alterar esta classe, vale lembrar que é uma função pl/java ou seja ela é executada do lado do banco de dados, então é necessário instalar o novo jar no banco para que o mesmo funcione


#6

Essa alteração ela resolve em partes, pois, analisando o código dessa fução verifica-se que o problema pode ocorrer com vários níveis de lista de materiais, ou seja, se na lista de materiais do produto A tenha um produto B que tem A na lista, o erro também ocorre. Acredito eu que seria implementar uma busca antes de salvar algum elemento na lista de materiais. Ou seja, verificar a existencia de algum ciclo.