Générer un ID unique à la création

Bonjour à tous,
S’il vous plait je cherche une façon d’implémenter cet impact qui ne fonctionne toujours pas pour moi :

[EXPR:Tool.format("NEW-%05d", Long.valueOf([ROWID]))]

Elle devrait généré un ID unique en création d’objet, la contrainte est BACK avec condition [ISNEW]

J’ai essayé de l’implémenter dans default value de l’object field mais ceci met tout le temps cette valeur quand j’importe en CSV alors que le CSV comporte déjà une valeur, sachant que je travail avec des Business Object tool et j’applique à chaque enregistrement un validateAndSave();

Avez vous des préconisation s’il vous plait ? merci d’avance

Utiliser le row ID pour générer un identifiant métier est toujours subtil car il y a généralement un effet d’ “oeuf et de poule” surtout si cet attribut fait partie de la clé fonctionnelle

A une époque (en versions 3.x) il était possible de mettre une expression de ce type ([EXPR:Tool.format("ABC-%05d", Long.valueOf([ROWID]))]) dans la valeur par défaut d’un attribut ad hoc. Je ne sais pas si c’est encore possible dans les versions plus récentes 4.0 et 5.x.

Personnellement je préfère toujours utiliser un param système “séquence” à part genre:

setFieldValue("myField", Tool.format("ABC-%05d", getGrant().getNextSystemParamValue("MY_SEQUENCE"));

dans un bloc synchronized appelé depuis le postValidate (et en ayant mis une valeur par défaut “statique” sur l’attribut pour qu’il passe le validate, ex: ABC-00000 dans mon exemple)

Bonjour David,
Merci pour votre réponse ça marche pour la génération l’ID Unique lors de création d’un grâce au formulaire.
Sauf qu’en import CSV, même en renseignant ce champs dans avec des setFieldValues et puis un validateAndSave() sur un business object tool, ceci remplace la valeur renseigné pour ce champ, avec l’ID unique générer.
Voici le bout de code de mon adapter csv :

		//Processing for "Projet"
								List<String[]> rs = projetBot.search(new JSONObject()
								.put("numero_projet", values[3])
								.put("numLigneContrat", values[1])
								);
							
								if (rs.size() == 1) // 1 found = do nothing
									projetBo.setValues(rs.get(0), true);	
								
								
								else if (rs.size() == 0) // 0 found => create
									{
									projetBo.resetValues(true); 
									
									//Processing for "contrat"
									rs = contratBot.search(new JSONObject().put("numContrat", values[0]));
								
									if (rs.size() == 1) // 1 found = do nothing
									contratBo.setValues(rs.get(0), true);
									
									else if (rs.size() == 0) // 0 found => create
									contratBo.resetValues(true); //
								
									else // Should never happen if search is done using all functional keys
									throw new Exception(rs.size() + " contact records found");
								
									contratBo.setFieldValue("numContrat", values[0]);
									
									//Setting code for TypeContract Enum
									if (values[7].equals("Forfait"))
									codeTypeContract = "FORFAIT";
									else if (values[7].equals("Date à date"))
									codeTypeContract = "DATEADATE";
									else if (values[7].equals("Epuisements de jours"))
									codeTypeContract = "EPUISEMENT";
									else 
									codeTypeContract = "AUTRE";
			
									contratBo.setFieldValue("TypeContrat", codeTypeContract);	  
									contratBot.validateAndSave();
									
									//Processing for "ChefProjet"
									rs = chefprojetBot.search(new JSONObject()
									.put("usr_last_name", values[6].split(",[ ]*")[0])
									.put("usr_first_name",values[6].split(",[ ]*")[1])
									);
								
									if (rs.size() == 1) // 1 found = do nothing
									chefprojetBo.setValues(rs.get(0), true);	
									
									else if (rs.size() == 0) // 0 found => create
									chefprojetBo.resetValues(true); // 
								
									else // Should never happen if search is done using all functional keys
									throw new Exception(rs.size() + " records found");
									
									chefprojetBo.setFieldValue("usr_last_name", values[6].split(",[ ]*")[0]);
									chefprojetBo.setFieldValue("usr_first_name", values[6].split(",[ ]*")[1]);	  
									chefprojetBot.validateAndSave();
									
									//Create/Update "Projet"
									projetBo.setFieldValue("numero_projet", values[3]);
									projetBo.setFieldValue("orgaProjet", values[2] );	  
									projetBo.setFieldValue("nomProjet", values[4] );
									projetBo.setFieldValue("nomTacheSup", values[5]);
									projetBo.setFieldValue("Projet_Contrat_id", contratBo.getRowId());
									projetBo.setFieldValue("Projet_ChefProjet_id",chefprojetBo.getRowId());
									projetBo.setFieldValue("numLigneContrat", values[1] );	  
								
									projetBot.validateAndSave();
			
									}

Avez vous des préconisations svp ? Merci

Votre question est plus large => si vos imports batch induisent des règles de gestion différentes de celles appliquées dans un usage UI utilisez des instances différentes et faites le test sur le nom d’instance:

Ex: en batch, si vous êtes dans un adapter specifique, instanciez une instance (préfixée par eai_) (comme le fait le socle sur les imports standards CSV & XML)

ObjectDB obj = getGrant().getBatchObject("MyObject");

Dans tous les cas, dans le code de votre objet conditionnez la valorisation de l’attribut (ou tout autre règle de gestion non applicable en batch) à:

if (!isBatchInstance()) {
    ...
}

Merci ça marche parfaitement