Transitions d'état qui disparaissent aléatoirement

Request description

Bonjour,

Nous avons un problème qui revient souvent mais de façon aléatoire en production. Je pense qu’il s’agit du même que celui mentionné dans ce ticket.

Nous avons 3 objets utilisant 3 champs statut distincts. Ces 3 champs sont basés sur la même liste de valeur et partagent les mêmes transitions d’état.
De temps en temps, les transitions d’état disparaissent de l’un de ces objets, ce qui provoque cette erreur.

Si je regarde l’onglet Network, je vois en effet que les transitions d’état sont disponible sur mon objet qui n’a pas le souci

mais pas sur celui qui provoque l’erreur

Après un clear cache, tout revient à la normale sur tous les objets.

Je n’arrive pas à identifier le mode opératoire qui mène à cette erreur.
Auriez vous une piste ?

Merci d’avance
Emmanuelle

Bonjour,

Le problème n’ayant pas été suivi ni reproduit, le ticket avait été fermé automatiquement.
J’avais donné qq pistes d’analyse/vérif dans le post mentionné.
Les as-tu vérifiés ?

Le point commun c’est d’utiliser plusieurs fois une même liste pour plusieurs statuts. Normalement les transitions d’états sont instanciées par objet, il ne devrait pas y avoir de collision. On pourrait les redéfinir 3 fois à titre préventif ou de quarantaine pour voir.

Les transitions sont statiques (définies en base) ou existe-il du code qui change les ENUM à la volée ?

La copie d’écran montre une confirmation d’action, tu es sur une action de formulaire ou dans quel contexte d’usage ? Les transitions ne remontent pas toujours suivant le contexte d’usage : par soucis d’optimisation, elles ne sont pas envoyées hors CONTEXT_UPDATE d’un formulaire ou d’un edit-row.

Merci de ton retour rapide,
J’avais vérifié qu’on retournait bien super.isActionEnable, pour le reste je pense que comme un CC règle le souci ce n’est pas un problème d’habilitations.

Les transitions sont statiques

Le problème survient sur rciAppSub et pas sur rciApplication.
Quand cela arrive, on voit que l’objet rciAppSub n’a plus les actions de transition d’état affichées (en liste ou en form)
Il s’agit d’une action custom qui change successivement les statuts de rciApplication (ok) puis rciAppSub (ko) puis rciAccountableAppsub (ko aussi il me semble)

Au cas où cela puisse jouer un rôle, mes 3 objets héritent d’une même classe partagée. Je peux peut-être mettre des traces quelque part pour la prochaine fois où ça se reproduit ?

Oui il faudrait nous donner l’extrait de code (hérité ou non) de ces actions et les logs éventuelles, ainsi que les hooks qui pourraient modifier le comportement :

initUpdate
pre/postValidate
isStateTransitionEnable
isActionEnable
...

Par défaut, un “save” automatique est fait avant d’appeler la méthode de l’action pour vérifier les données, donc il faudrait savoir si c’est lui ou le code de l’action qui sort en ValidateException.

On va revérifier comment se recharge la liste des états courants au select/setValues.
Il doit y avoir qq choses qui parfois change la liste des états (ou les transitions) entre le select et le validate&save et provoque un ERR_ENUM (code inconnu). Le validate essaye d’être malin mais même en ayant rechargé la liste d’après la valeur du statut précédent, le nouveau statut/code d’après les transitions n’y est pas/plus.

Alors il y a pas mal de code et pour l’action ce n’est pas moi qui l’ai fait, je vais essayer de ne rien oublier. J’espère que ça sera lisible :confused:

Le code de l’action

//Ask for validation of Application, Scopes and Accountables 
	public List<String> askForValidation(Action action)
	{
		List<String> res =new ArrayList<String>();
		
		res = askOrCancelValidation(action, "ASK");
		if (res != null) 
		{
			AppLog.info("AEK askOrCancelValidation res = "+res, getGrant());
			return res;
		}
		return null;
	}

public List<String> askOrCancelValidation(Action action, String act)
	{
		AppLog.info(getClass(), "AEK askOrCancelValidation : "," act = " + act, getGrant());

		String actTxt = act.equals("CANCEL") ? "canceled " : "";
		String DiretcUrl = Grant.getSystemAdmin().getParameter("DIRECT_URL");
		String env = (DiretcUrl.equals("https://ear.k8s-prod.grouperci.com") ? "" : DiretcUrl) ;
	    Grant grant = getGrant();
		String l = grant.getLang();	    
		grant.setParameter("ASKORCANCEL", "true");
		
		
		List<String> notifApp = new ArrayList<String>();
		List<String> notifScope = new ArrayList<String>();
		List<String> notifAcc = new ArrayList<String>();
		List<String> validScopeRcpts = new ArrayList<String>(), validAccRcpts = new ArrayList<String>();
		String notifAppAsString = "";
		String notifScopeAsString = "";
		String notifAccAsString = "";
		List<String> res =new ArrayList<String>();

		try
		{
			String app = action.getConfirmField(getGrant().getLang(),ASKFORVALAPP_FIELDNAME).getValue();
			
			if (app.equals("1")) {
				res = askOrCancelValidationApp(act,notifApp,notifAcc,validAccRcpts);
				if (res != null) 
				{
					AppLog.info("AEK askOrCancelValidation/askOrCancelValidationApp res = "+res, getGrant());
					grant.setParameter("ASKORCANCEL", "false");
					return res;
				}				
				// Send notification for App :
				notifAppAsString = String.join("\n", notifApp); 
				Alert a = getAlert("RciAlertaskOrCancelValidationApp", Alert.TYPE_INFO);
				if (a!=null) {
					a.setSubject(l,a.getSubject(l).replace("[ACTION]",actTxt));
					a.setContent(l,a.getContent(l).replace("[ENV]",((env.isEmpty()) ? "" : " !!! ATTENTION !!! THIS ENVIRONNEMENT IS " + env)));					
					a.setContent(l,a.getContent(l).replace("[LIST]",notifAppAsString).replace("[ACTION]",actTxt).replace("[APP]",this.getFieldValue("rciAppName")));
					a.setRecipentTO(getValidationRecipients());
	    			a.send(this);
				}
			}

			String[] scope = action.getConfirmField(getGrant().getLang(),ASKFORVALSCOPES_FIELDNAME).getCodes();
			if (scope != null)
			{									AppLog.info("EFE askOrCancelValidation 1"+ Integer.toString(validScopeRcpts.size()), getGrant());

				res = askOrCancelValidationScopes(scope,act,notifScope,notifAcc,validScopeRcpts,validAccRcpts);
									AppLog.info("EFE askOrCancelValidation 2"+ Integer.toString(validScopeRcpts.size()), getGrant());

				
				if (res != null) 
				{
					AppLog.info("AEK askOrCancelValidation/askOrCancelValidationScopes res = "+res, getGrant());
					grant.setParameter("ASKORCANCEL", "false");
					return res;
				}				

				// Send notification for Scopes :
				notifScopeAsString = String.join("\n", notifScope); 
				Alert a = getAlert("RciAlertaskOrCancelValidationScope", Alert.TYPE_INFO);
				if (a!=null) {
					a.setSubject(l,a.getSubject(l).replace("[ACTION]",actTxt));
					a.setContent(l,a.getContent(l).replace("[ENV]",((env.isEmpty()) ? "" : " !!! ATTENTION !!! THIS ENVIRONNEMENT IS " + env)));					
					a.setContent(l,a.getContent(l).replace("[LIST]",notifScopeAsString).replace("[ACTION]",actTxt).replace("[APP]",this.getFieldValue("rciAppName")));
					a.setRecipentTO(validScopeRcpts);
						AppLog.info("EFE askOrCancelValidation 3"+ Integer.toString(validScopeRcpts.size()), getGrant());
	    			a.send(this);				
				}
			}
			
//			if (notifAcc != null) {
			if (!notifAcc.isEmpty()) {
				// Send notification for Accountables :
				notifAccAsString = String.join("\n", notifAcc); 
				Alert a = getAlert("RciAlertaskOrCancelValidationAcc", Alert.TYPE_INFO);
				if (a!=null) {
				 //   if (act.equals("CANCEL")) a.setSubject("ENU", "List of canceled accountable validation requests");
					// a.setContent("ENU", notifAccAsString);

					a.setSubject(l,a.getSubject(l).replace("[ACTION]",actTxt));
					a.setContent(l,a.getContent(l).replace("[ENV]",((env.isEmpty()) ? "" : " !!! ATTENTION !!! THIS ENVIRONNEMENT IS " + env)));					
					a.setContent(l,a.getContent(l).replace("[LIST]",notifAccAsString).replace("[ACTION]",actTxt).replace("[APP]",this.getFieldValue("rciAppName")));
					a.setRecipentTO(validAccRcpts);
	    			a.send(this);
				}
			}

			AppLog.info("AEK LOG !!!",getGrant());
			AppLog.info("AEK notifAppAsString = " + notifAppAsString,getGrant());
			AppLog.info("AEK notifScopeAsString = " + notifScopeAsString,getGrant());
			AppLog.info("AEK notifAccAsString = " + notifAccAsString,getGrant());
		}
		catch (Exception e) {
				grant.setParameter("ASKORCANCEL", "false");			
				AppLog.error(e, getGrant());
		}
		grant.setParameter("ASKORCANCEL", "false");		
		return null;
	}

public List<String> askOrCancelValidationApp(String act, List<String> notifApp, List<String> notifAcc, List<String> validAccRcpts)
	{
		String msg = "";
		Grant g = getGrant();
		String val = "";
		if (act.equals("ASK")) { 
			AppLog.info("AEK record status " + val, getGrant());
			val = RECORDSTATUS_TOBEVALIDATED;
			msg = g.getParameter("AskForValApp");
		} else {
			val = this.getFieldValue("rciStatusBeforeTbv");
			msg = g.getParameter("CancelAskForValApp");
		}
		this.setFieldValue("rciAppRecordstatus",val);
		List<String> res =new ArrayList<String>();
		res = this.validate();
		if (res != null) 
		{
			return adaptErrorMessages(res, "Application " +this.getFieldValue("rciAppName"));	
		}
		
		pauseCheckCompletion();
		this.save();
		setCheckCompletion();
		
		AppLog.info("AEK action askOrCancelValidation : App = "+getRowId() + " " + this.getFieldValue("rciAppName"), getGrant());
    	String appUrl = HTMLTool.getDirectURL(getGrant(),"RciApplication",  this.getRowId());
		notifApp.add(msg + " <a href='" + appUrl + "' style='color: blue'>" + this.getFieldValue("rciAppName")+ "</a>");

		res = askOrCancelValidationAccAppLvl(act, notifAcc,validAccRcpts);			
		if (res != null) 
		{
			AppLog.info("AEK askOrCancelValidationApp/askOrCancelValidationAccAppLvl res = "+res, getGrant());
			return res;
		}							
		
		return null;
	}

	public List <String> askOrCancelValidationAccAppLvl(String act, List<String> notifAcc,List<String> validAccRcpts)
	{
		List<String> res =new ArrayList<String>();
		String msg = "";
		Grant g = getGrant();
		String s =  "";
		
		if (act.equals("ASK")) {
				msg = g.getParameter("AskForValAccApp");
				s ="'"+RECORDSTATUS_DRAFT+"','"+RECORDSTATUS_TOREVIEW+"'";
		} else {
				msg = g.getParameter("CancelAskForValAccApp");
				s ="'"+RECORDSTATUS_TOBEVALIDATED+"'";
		}
		
		RciAccountableAppsub accountables = (RciAccountableAppsub) getGrant().getTmpObject("RciAccountableAppsub");
		accountables.resetFilters();
		accountables.setFieldFilter("rciAccAppId", this.getRowId());
		accountables.setFieldFilter("rciAccAppsubRecordStatus", " in (" + s + ")");
		if (getGrant().getParameter("MIGRATION_PAUSE").equals("1") && !getGrant().hasResponsibility("DESIGNER"))  accountables.getField("created_by").setFilter("!='designer-migration'");

		List<String[]> rowsAcc = accountables.search();
		
		for (int j = 0; rowsAcc != null && j < rowsAcc.size(); j++) {
		    accountables.select(rowsAcc.get(j)[0]);
			String val = (act.equals("ASK")) ? RECORDSTATUS_TOBEVALIDATED : accountables.getFieldValue("rciStatusBeforeTbv");
AppLog.info("AEK askOrCancelValidationAccAppLvl val = " + val, getGrant());
		    accountables.setFieldValue("rciAccAppsubRecordStatus",val);
		    res = accountables.validate();
			if (res != null) 
			{
				AppLog.info("AEK askOrCancelValidationAccAppLvl res = "+res, getGrant());
				return adaptErrorMessages(res, "Accountable app level " +accountables.getFieldValue("rciAccAppsubTypeId.rciAccTypeName"));	
			}						    
		    accountables.save();
    		AppLog.info("AEK action askOrCancelValidation : Acc App = " +this.getRowId()+ " " + this.getFieldValue("rciAppName")+ " Acc = " +accountables.getRowId() + " "+ accountables.getFieldValue("usr_first_name") + " " + accountables.getFieldValue("usr_last_name") + " - "+accountables.getFieldValue("rciAccAppsubTypeId.rciAccTypeName"), getGrant());
    		String appUrl = HTMLTool.getDirectURL(getGrant(),"RciAccountableAppsub",  accountables.getRowId());
			notifAcc.add("<br/>"+msg+ " "+ this.getFieldValue("rciAppName")+ " Acc = " + "<a href='" + appUrl + "' style='color: blue'>" + accountables.getFieldValue("usr_first_name") + " " + accountables.getFieldValue("usr_last_name") + "</a> - " + " - "+accountables.getFieldValue("rciAccAppsubTypeId.rciAccTypeName")+"<br/>");
		}
		
		validAccRcpts.addAll(accountables.getValidationRecipients());
		
		return null;
	}
	
	/*EFE review ici je pense qu'on peut optimiser , la requête sur les scopes au statut X a déjà été faite dans le initAction
	- si ALL prendre tous les rowid de l'action pour éviter de requêter de nouveau les scopes de l'app et passer la liste ici en paramètre
	- sinon passer en paramètre la liste des rowid de scope cochés et supprimer la boucle for dans la fonction appelante
	
	REnommer fonction en AskOrCancel ?
	*/
	public List<String> askOrCancelValidationScopes(String[] scope, String act, List<String> notifScope,List<String> notifAcc, List<String> validScopeRcpts, List<String> validAccRcpts)
	{
		List<String> res =new ArrayList<String>();
		String msg = "";
		Grant g = getGrant();
		String s = "";
		
		if (act.equals("ASK")) {
				msg = g.getParameter("AskForValScope");
				s ="'"+RECORDSTATUS_DRAFT+"','"+RECORDSTATUS_TOREVIEW+"'";
		} else {
				msg = g.getParameter("CancelAskForValScope");
				s ="'"+RECORDSTATUS_TOBEVALIDATED+"'";
		}

		if (scope.length > 0) {
			int x = (scope[0].equals("ALL")) ? 1 : 0;
			
			RciAppSub appsub = (RciAppSub) getGrant().getTmpObject("RciAppSub");
			appsub.resetFilters();
			
			for (int i = x ; i < scope.length ; i++)
			{
			    appsub.select(scope[i]);
			    
				String val = (act.equals("ASK")) ? RECORDSTATUS_TOBEVALIDATED : appsub.getFieldValue("rciStatusBeforeTbv");
			    appsub.setFieldValue("rciAppsubRecordStatus",val);
			    res = appsub.validate();
				if (res != null) 
				{
					AppLog.info("AEK askOrCancelValidationScopes res = "+res, getGrant());
					return adaptErrorMessages(res, "Scope " +appsub.getFieldValue("rciSubScope"));	
				}		    
			    appsub.save();

	            String objName = "RciAppSubRRSG"; 
	            String filterField = "rciAppsubTechnicalId";
	            String rowid = appsub.getFieldValue("rciAppsubTechnicalId"); 
	
	            // Construct the URL to open the list of RciAppSubRRSG with the filter applied
	            String appUrl = Grant.getSystemAdmin().getParameter("DIRECT_URL") + HTMLTool.getListURL(objName, filterField + "=" + rowid);
				AppLog.info("AEK action askOrCancelValidation : appUrl = "+ appUrl + " / rciSubScope = " + appsub.getFieldValue("rciSubScope") + " rciAppsubTechnicalId = " + rowid + " notifScope = " +notifScope, getGrant());
				
//			    AppLog.info("AEK action askOrCancelValidation : Scope = "+ appsub.getFieldValue("rciSubScope") + " RowId = " + scope[i] + " notifScope = " +notifScope, getGrant());
//	    		String appUrl = HTMLTool.getDirectURL(getGrant(),"RciAppSub",  scope[i]);
				notifScope.add("<br/>"+msg+ " <a href='" + appUrl + "' style='color: blue'>" +  appsub.getFieldValue("rciSubScope")+ "</a>"+ " / Technical Id = "+ appsub.getFieldValue("rciAppsubTechnicalId")+"</br>");
	
				res = askOrCancelValidationAccScopeLvl(act, scope[i],appsub.getFieldValue("rciSubScope"), notifAcc, validAccRcpts);			
				if (res != null) 
				{
					AppLog.info("AEK askOrCancelValidationScopes/askOrCancelValidationAccScopeLvl res = "+res, getGrant());
					return res;
				}				
			}
			
			validScopeRcpts.addAll(appsub.getValidationRecipients());
			AppLog.info("EFE askOrCancelValidationScopes "+ Integer.toString(validScopeRcpts.size()), getGrant());
		}
		return null;
	}

	public List <String> askOrCancelValidationAccScopeLvl(String act, String rowid, String scope, List<String> notifAcc, List<String> validAccRcpts)
	{
		List<String> res =new ArrayList<String>();
		String msg = "";
		Grant g = getGrant();
		String s = 		 "";
		
		if (act.equals("ASK")) {
				msg = g.getParameter("AskForValAccScope");
				s ="'"+RECORDSTATUS_DRAFT+"','"+RECORDSTATUS_TOREVIEW+"'";
		} else {
				msg = g.getParameter("CancelAskForValAccScope");
				s ="'"+RECORDSTATUS_TOBEVALIDATED+"'";
		}

		RciAccountableAppsub accountables = (RciAccountableAppsub) getGrant().getTmpObject("RciAccountableAppsub");
		accountables.resetFilters();
		accountables.setFieldFilter("rciAccAppsubRecordStatus", " in (" + s + ")");
		accountables.setFieldFilter("rciAccAppsubId",rowid);											// Only for this Scope 


		List<String[]> rowsAcc = accountables.search();

		for (int j = 0; rowsAcc != null && j < rowsAcc.size(); j++) {
		    accountables.select(rowsAcc.get(j)[0]);
			String val = (act.equals("ASK")) ? RECORDSTATUS_TOBEVALIDATED : accountables.getFieldValue("rciStatusBeforeTbv");
		    accountables.setFieldValue("rciAccAppsubRecordStatus",val);
		    res = accountables.validate();
			if (res != null) 
			{
				AppLog.info("AEK askOrCancelValidationAccScopeLvl res = "+res, getGrant());
				return adaptErrorMessages(res, "Accountable scope level " +accountables.getFieldValue("rciAccAppsubTypeId.rciAccTypeName"));	
			}		    
		    accountables.save();
    		AppLog.info("AEK action askOrCancelValidation : Acc Scope = " +scope+ " Acc = " +accountables.getRowId() + " "+ accountables.getFieldValue("usr_first_name") + " " + accountables.getFieldValue("usr_last_name") + " - "+accountables.getFieldValue("rciAccAppsubTypeId.rciAccTypeName"), getGrant());	
    		String appUrl = HTMLTool.getDirectURL(getGrant(),"RciAccountableAppsub",  accountables.getRowId());
			notifAcc.add("<br/>"+msg+ " " + scope + " Acc = " + "<a href='" + appUrl + "' style='color: blue'>" + accountables.getFieldValue("usr_first_name") + " " + accountables.getFieldValue("usr_last_name") + "</a> - " + accountables.getFieldValue("rciAccAppsubTypeId.rciAccTypeName") + "</br>");
		}
		
		validAccRcpts.addAll(accountables.getValidationRecipients());
		
		return null;
	}

Init update de la classe partagée mère des 3 objets

	@Override
	public void initUpdate() {

		if (!canEdit() && !isScope())
		{
			setReadOnly();
		}
		else
			setUpdatable();

		super.initUpdate();
	}
	
	public void setReadOnly()
	{
		for (ObjectField f : getFields())
		{
			if (f.getVisibility() != ObjectField.VIS_HIDDEN && f.getVisibility() != ObjectField.VIS_FORBIDDEN && f != getStatusField())
				f.setUpdatable(ObjectField.UPD_READ_ONLY);
		}
	}
	
	public void setUpdatable()
	{
		for (ObjectField f : getFields())
		{
			if (f.getVisibility() != ObjectField.VIS_HIDDEN && f.getVisibility() != ObjectField.VIS_FORBIDDEN && f != getStatusField())
				f.setUpdatable(f.getUpdatableDefault());
		}
	}

Prevalidate

RciApplication

	// @Override
	public List<String> preValidate() {
										AppLog.info(getClass(), "preValidate EFE : ", getFieldValue("rciAppRecordstatus"), getGrant());

		String cmdbUser = getGrant().getSystemParam("CMDB_USER");
				
		if (!cmdbUser.equals(getGrant().getLogin()) && !getField("rciAppCmdbOverwrite").hasChanged())
			setFieldValue("rciAppCmdbOverwrite", true);
		
		if (isNew() && !isCreateBackup())
		{
			int inc = Integer.parseInt(getGrant().getSystemParam("RCI_APP_TECHNICAL_ID_" + getGrant().getSystemParam("ENV")));
			inc += 1;
						AppLog.info(getClass(), "EFE preValidate : ", Integer.toString(inc), getGrant());
	
			getGrant().setSystemParam("RCI_APP_TECHNICAL_ID_" + getGrant().getSystemParam("ENV"), Integer.toString(inc), false, true, true);
			setFieldValue("rciAppTechnicalId", Tool.format("APP-%05d", inc));
		}
		
		return super.preValidate();
	}

RciAppSub

	@Override
	public List<String> preValidate() {
		List<String> msgs = new ArrayList<>();
		
		if (!isBatchInstance() && getGrant().getParameter("MIGRATION_MODE").equals("0"))
		{
			if (getStatusField().hasChanged())
			{
				if (getStatus().equals("TOBEVALID") && !isNew())
				{
					ObjectDB respEnt = getGrant().getTmpObject("RciAppsubRspent");
					respEnt.resetFilters();
					respEnt.setFieldFilter("rciAppsubRspentAppsubId", this.getRowId());
					
					if (respEnt.search().size() == 0)
						msgs.add(Message.formatError("ERR_NORESPENT", null, "")); // Field error message
	
				}
				
				if ((getStatus().equals("TOBEVALID") || getStatus().equals("VALID")) && !isNew())
				{
					if (getField("rciAppOrgdomId").isEmpty())
						msgs.add(Message.formatError("ERR_NOORG", null, "")); // Field error message
				}
				
				if (msgs.size() > 0)
					return msgs;
			}
		}
		
		return super.preValidate();
	}

Post validate

RciApplication

@Override
	public List <String> postValidate()
	{
										AppLog.info(getClass(), "EFE 4 : ", getFieldValue("rciAppState"), getGrant());
		if (!isBatchInstance() && getGrant().getParameter("MIGRATION_MODE").equals("0"))
		{
			String msg = "";
			List<String> msgs = new ArrayList<String>();
			
			if (!getField("rciAppIdentifier").isEmpty() && !getFieldValue("rciAppIdentifier").startsWith("IRN-")){
				msg = "IRN must start with IRN-xxxxx !";
				msgs.add(Message.formatError(msg, null, "rciAppIdentifier")); // Field error message
				return msgs; // Return a list of messages
			}
			
			if (getField("rciAppOrgdomId").hasChanged()) this.updatePrincipalIts(); //In case of organizational changes, we update the main contact for the app
			
			// In case of status change to TBV, we check if the app has at least one scope
			if ((getStatus().equals("TOBEVALID") || getStatus().equals("VALID")) && !isNew() && (!isBatchInstance() && getGrant().getParameter("MIGRATION_MODE").equals("0")))
			{	
				ObjectDB scopes = getGrant().getObject("EXISTS_","RciAppSub");
				// ObjectDB scopes = getGrant().getObject("Unique","RciAppSub");
				// BusinessObjectTool otScopes = scopes.getTool();
				scopes.resetFilters();
				scopes.setFieldFilter("rciAppsubAppId", getRowId());
				List<String[]> rowsScopes = scopes.search();
				if (rowsScopes.size() < 1){
					msg = "You must create a scope for this application in order to ask for validation !";
					msgs.add(Message.formatError(msg, null, "")); // Field error message
					return msgs; // Return a list of messages
				}
	    		
			}
			
		/*	if (getFieldValue("rciAppOrgdomId").isEmpty() && getFieldValue("rciAppDivision").equals(DIVISION_LOCAL) && !this.getInstanceName().equals("merge_ajax_RciApplication")  && (!isBatchInstance() || getGrant().getParameter("MIGRATION_MODE").equals(false))) 
			{
				List<String> msgs = new ArrayList<String>();
				msgs.add(Message.formatError("ERR_NOORG", null, "")); // Field error message
	    		return msgs; // Return a list of messages
				
			}*/

AppLog.info("AEK X this.getInstanceName() = " + this.getInstanceName() + " row_id " + getRowId() + " backup " + getFieldValue("rciAppIsBackup"), getGrant());			
			if (!getFieldValue("rciAppIdentifier").isEmpty() && !this.getInstanceName().equals("merge_ajax_RciApplication") && getField("rciAppIsBackup").getBoolean() == false  && !isBatchInstance() && getGrant().getParameter("MIGRATION_MODE").equals("0"))
			{	
				ObjectDB app = getGrant().getObject("UNIQUE_","RciApplication");
				BusinessObjectTool otApp = app.getTool();
				app.resetValues();
				app.setFieldFilter("rciAppIdentifier", this.getFieldValue("rciAppIdentifier"));
				app.setFieldFilter("row_id","!= " + getRowId());
				app.setFieldFilter("rciFieldIsArchived", false);
				app.setFieldFilter("rciAppIsBackup", false);
				
				
				List<String[]> rowsApp = app.search();
		
				if (rowsApp.size() > 0) // Applicaion already created
				{
				    app.select(rowsApp.get(0)[0]);
					String appUrl = HTMLTool.getFormURL("RciApplication", "the_ajax_RciApplication", app.getRowId(), "nav=new");
					msg = "This application already exists ! <br> <a href='"+appUrl+"' style='color: blue'>--> Access application</a>";
					msgs.add(Message.formatError(msg, null, "")); // Field error message
					return msgs; // Return a list of messages
				} 
			}
							AppLog.info(getClass(), "postValidate : ", "END" + getFieldValue("rciAppValidationStatus"), getGrant());
		}
		
		return super.postValidate();
	}

RciAppSub

@Override
	public List <String> postValidate()
	{	
		if (!isBatchInstance() && getGrant().getParameter("MIGRATION_MODE").equals("0"))
		{		
			
			String msg = "";
			List<String> msgs = new ArrayList<String>();
			
			if (!getField("rciAppsubIdentifier").isEmpty() && !getFieldValue("rciAppsubIdentifier").startsWith("IRN-")){
				msg = "IRN must start with IRN-xxxxx !";
				msgs.add(Message.formatError(msg, null, "rciAppsubIdentifier")); // Field error message
				return msgs; // Return a list of messages
			}
			
			if (getStatusField().hasChanged() && this.getStatus().equals(RECORDSTATUS_VALID))
			{
				Grant grant = getGrant();
				String l = grant.getLang();	
				
				ObjectDB ccaLine = getGrant().getTmpObject("RciCca");
				ccaLine.setFieldFilter("rciCcaScopeId", this.getRowId());
				List<String[]> rowsCca = ccaLine.search();
		
				if (rowsCca.size() > 0) 
				{
				    ccaLine.select(rowsCca.get(0)[0]);
			    	String ccaUrl = HTMLTool.getDirectURL(getGrant(),"RciCca",  ccaLine.getRowId());
					msg = "</p> <a href='" + ccaUrl + "' style='color: blue'>" + this.getFieldValue("rciAppName")+ "</a>";	
	
					// Send notification for CCA Team  :
					AppLog.info("AEK postValidate appsub : scope = "+getRowId() + " " + this.getFieldValue("rciAppName"), getGrant());
					Alert a = getAlert("RciAlertScopeValidated", Alert.TYPE_INFO);
					if (a!=null) {
						a.setContent(l,a.getContent(l).replace("[LINK]",msg));
						a.send(this);				
					}
				} 
			}
		}
		return super.postValidate();
	}

RciAccountableAppsub

	@Override
	public List <String> postValidate()
	{	
		if (!getFieldValue("rciAccAppsubTypeId.rciAccTypeName").equals("IT SI") && getFieldValue("rciAccIsContact").equals("1"))
		{
			setFieldValue("rciAccIsContact",false); 
		}
		return super.postValidate();
	}

IsActionEnable

RciApplication

	@Override	
	public boolean isActionEnable(String[] row, String action) {
		if (!getGrant().hasResponsibility("DESIGNER") && getGrant().getParameter("BLOCAGE_ENV").equals("1")) return false;
		
		if (action.equals("viewAllApp"))
		{
			if (!getInstanceName().equals("home_ajax_RciApplication"))
				return false;
			
			if (!getGrant().getFlagParameter(INIT_FILTER_FLAG) && !getGrant().getFlagParameter(ARCHIVED_DISPLAY_FLAG))
				return false;
		}

		if (action.equals("viewActive")  && !getGrant().getFlagParameter(ARCHIVED_DISPLAY_FLAG))
		{
			if (!getInstanceName().equals("home_ajax_RciApplication"))
				return false;
				
			if (getGrant().getFlagParameter(INIT_FILTER_FLAG))
				return false;
		}

		if (!isUpdateEnable(row) && (action.equals("RCIB-SYNC-APP") || action.equals("askForValidation") || action.equals("cancelValidationRequest")))
			return false;

		if (action.equals("RCIAPPRECORDSTATUS-TOBEVALID") || action.equals("RCIAPPRECORDSTATUS-TOCANCEL"))
			return false;
		
		if (action.equals("RCIB-SYNC-APP") && getFieldValue("rciAppIdentifier").isEmpty())
			return false;
		
		if (action.equals("RCIB-APP-RESTORE") && getField("rciAppIsBackup").getBoolean() == false)
			return false;
		
		if (action.equals("askForValidation"))
			return checkaskOrCancelValidation("ASK");


		if (action.equals("cancelValidationRequest"))
			return checkaskOrCancelValidation("CANCEL");

		return super.isActionEnable(row, action);

	}

RciAppSub

	@Override
	public boolean isActionEnable(String[] row, String action) {
		if (!getGrant().hasResponsibility("DESIGNER") && getGrant().getParameter("BLOCAGE_ENV").equals("1")) return false;

		if (action.equals("RCI-APPSUB-VALIDATION-DELETION") && !isArchived())
			return false;
			
		if (!action.equals("RCI-APPSUB-VALIDATION-DELETION") && (isBackup() || isParentBackup()))	
			return false;
			
		return super.isActionEnable(row, action);
	}

RciAccountableAppsub

	@Override	
	public boolean isActionEnable(String[] row, String action) {
		
		if (action.startsWith("associate-RciApplication-rciAccAppId"))
			return false;
		
		if (action.equals("associate-RciAppSub-rciAccAppsubId-RciAccountableType-rciAccAppsubTypeId"))
			return false;
		
		return super.isActionEnable(row, action);

	}

Et la partie des logs qui concerne l’appel de l’action avec l’erreur

Blockquote
2024-11-18 13:34:18,508|SIMPLICITE|INFO||http://simplicite-dev-67bb8cd5f9-6ndrd:8080||INFO|designer|com.simplicite.objects.RCIB.RciApplication|askOrCancelValidationApp||Event: AEK action askOrCancelValidation : App = 4073 CECR - CONSOLIDATION ENGAGEMENT CLIENT FRANCE OPEN (RCI)
2024-11-18 13:34:18,508|SIMPLICITE|INFO||http://simplicite-dev-67bb8cd5f9-6ndrd:8080||SQLUSER|system|DBAccess|SQL|query|SQL=jdbc/simplicite: select t.row_id, null, t.rci_app_is_backup, t.rci_field_is_archived, t.rci_acc_appsub_record_status, null, t.rci_acc_appsub_type_id, t_rciAccAppsubTypeId.rci_acc_type_name, null, null, t.rci_acc_appsub_id, t_rciAccAppsubId.rci_appsub_app_id, t_rciAppsubAppId.rci_app_name, t_rciAppsubAppId.rci_app_technical_id, t_rciAccAppsubId.rci_appsub_sub_id, t_rciAppsubAppId.rci_app_division, t_rciAppsubAppId.rci_app_is_backup, t_rciAppsubAppId.rci_app_version, t_rciAccAppId.rci_app_cty_grp_id, t_rciAppsubSubId.rci_sub_cou_id, t_rciAppCtyId.cty_code2, t_rciAppsubSubId.rci_sub_name, t_rciSubCouId.cty_code2, t_rciAppsubSubId.rci_sub_scope, t_isoCtyCtygrpId.iso_ctygrp_code, t_rciSubCouId.iso_cty_ctygrp_id, t_rciAccAppsubId.rci_appsub_record_status, t.rciaccountable_user_id, t_RciAccountable_User_id.usr_login, t_RciAccountable_User_id.usr_first_name, t_RciAccountable_User_id.usr_last_name, t_RciAccountable_User_id.usr_email, t.rci_acc_responsibilities, t.rci_acc_is_contact, t.rci_acc_role, t_RciAccountable_User_id.rci_usr_role, t.rci_acc_app_id, t_rciAccAppId.rci_app_name, t_rciAccAppId.rci_app_technical_id, t_rciAccAppId.rci_app_version, t_rciAccAppId.rci_app_cty_id, t_rciAppCtyId.iso_cty_ctygrp_id, t.rci_status_before_tbv, t.rci_status_updated_dt, t.rci_acc_key, t.rci_wkf_completion, t.created_dt, t.created_by, t.updated_dt, t.updated_by from rci_accountable_appsub t left outer join rci_accountable_type t_rciAccAppsubTypeId on (t.rci_acc_appsub_type_id=t_rciAccAppsubTypeId.row_id) left outer join rci_app_sub t_rciAccAppsubId on (t.rci_acc_appsub_id=t_rciAccAppsubId.row_id) left outer join rci_application t_rciAppsubAppId on (t_rciAccAppsubId.rci_appsub_app_id=t_rciAppsubAppId.row_id) left outer join rci_application t_rciAccAppId on (t.rci_acc_app_id=t_rciAccAppId.row_id) left outer join rci_subsidiary t_rciAppsubSubId on (t_rciAccAppsubId.rci_appsub_sub_id=t_rciAppsubSubId.row_id) left outer join iso_country t_rciAppCtyId on (t_rciAccAppId.rci_app_cty_id=t_rciAppCtyId.row_id) left outer join iso_country t_rciSubCouId on (t_rciAppsubSubId.rci_sub_cou_id=t_rciSubCouId.row_id) left outer join iso_country_grouping t_isoCtyCtygrpId on (t_rciSubCouId.iso_cty_ctygrp_id=t_isoCtyCtygrpId.row_id) left outer join m_user t_RciAccountable_User_id on (t.rciaccountable_user_id=t_RciAccountable_User_id.row_id) where ( t.rci_acc_appsub_record_status in (‘DRAFT’,‘TOREVIEW’)) and (t.rci_acc_app_id=?) order by t_rciAppsubSubId.rci_sub_scope asc, t.rci_acc_role asc, t.rci_acc_key asc, t.row_id asc Hosts=[4073]
2024-11-18 13:34:18,513|SIMPLICITE|INFO||http://simplicite-dev-67bb8cd5f9-6ndrd:8080||SQLUSER|system|DBAccess|SQL|query|SQL=select u.usr_email from m_user u, m_resp r, m_group g where u.row_id = r.rsp_login_id and g.row_id = r.rsp_group_id and g.grp_name in ( ‘RCI_PROFILE_METHODS’,‘RCI_PROFILE_METHODS_CORP’) AND u.rci_usr_cty_id = 75 Hosts=
2024-11-18 13:34:18,517|SIMPLICITE|INFO||http://simplicite-dev-67bb8cd5f9-6ndrd:8080||SQLUSER|system|DBAccess|SQL|query|SQL=select u.usr_email from m_user u, m_resp r, m_group g where u.row_id = r.rsp_login_id and g.row_id = r.rsp_group_id and g.grp_name = ‘RCI_PROFILE_ARCHITECT’ AND u.rci_usr_cty_id = 75 Hosts=
2024-11-18 13:34:18,519|SIMPLICITE|INFO||http://simplicite-dev-67bb8cd5f9-6ndrd:8080||SQLUSER|system|DBAccess|SQL|query|SQL=select distinct usr_lang from m_user where usr_lang<>‘ENU’ and usr_email in (‘emmanuelle.fenice-extern@mobilize-fs.com’,‘emmanuelle.fenice-extern@mobilize-fs.com’) order by usr_lang asc Hosts=
2024-11-18 13:34:18,568|SIMPLICITE|INFO||http://simplicite-dev-67bb8cd5f9-6ndrd:8080||INFO|designer|com.simplicite.bpm.Alert|send||Event: ALERT:RciAlertaskOrCancelValidationApp. Email send: List of application validation requests
2024-11-18 13:34:18,568|SIMPLICITE|INFO||http://simplicite-dev-67bb8cd5f9-6ndrd:8080||ICOREAL001|designer|com.simplicite.bpm.Alert|send||Alert=RciAlertaskOrCancelValidationApp Subject=List of application validation requests Body=

Hello, !!! ATTENTION !!! THIS ENVIRONNEMENT IS https://ear-dev.k8s-stage.grouperci.com

Below, you will find a list of application validation requests.

Ask for validation for App CECR - CONSOLIDATION ENGAGEMENT CLIENT FRANCE OPEN (RCI)

		Please connect <a href=https://ear-dev.k8s-stage.grouperci.com?f=RciApplication%3B4073>here</a> to take the necessary actions.<br/>
		<br/>
		<br/>
		Simplicité
	</p>
</body>
2024-11-18 13:34:18,568|SIMPLICITE|INFO||http://simplicite-dev-67bb8cd5f9-6ndrd:8080||INFO|designer|com.simplicite.objects.RCIB.RciApplication|askOrCancelValidation||Event: EFE askOrCancelValidation 10 2024-11-18 13:34:18,571|SIMPLICITE|INFO||http://simplicite-dev-67bb8cd5f9-6ndrd:8080||SQLUSER|system|DBAccess|SQL|query|SQL=jdbc/simplicite: select t.row_id, t.rci_app_bce_doms, t.rci_app_funct_doms, t.rci_updates_log, t.rci_app_version, t.rci_app_is_backup, t.rci_field_is_archived, t_rciAppOriginAppId.rci_app_technical_id, t.rci_app_origin_app_id, t_rciAppOriginAppId.rci_app_version, t.rci_app_identifier, t.rci_app_name, t.rci_app_long_name, t.rci_app_sia, t.rci_app_recordstatus, t.rci_app_level, t.rci_app_criticality, t.rci_app_outsourced, t.rci_app_mfs_criticality, t.rci_app_confidentiality, t.rci_app_drp, t.rci_app_state, t.updated_dt, t.rci_app_cmdb_updated, t.rci_app_cmdb_overwrite, t.rci_app_data_source, t.rci_app_description, t.rci_app_type, t.rci_app_type_id, t_rciAppTypeId.rci_app_type_name, t.rci_app_document_link, t.rci_app_group, t.rci_app_corp, t.rci_app_cty_id, t_rciAppCtyId.cty_code2, t_rciAppCtyId.iso_cty_ctygrp_id, t.rci_app_cty_grp_id, t_rciAppCtyGrpId.iso_ctygrp_code, null, t.rci_app_division, t.rci_app_tag, t.rci_app_copyid, t.rci_app_cmsi_rit, t_rciAppCmsiRit.rci_user_full_name, t_rciAppCmsiRit.usr_login, t.rci_app_cmsi_rm, t_rciAppCmsiRm.rci_user_full_name, t_rciAppCmsiRm.usr_login, t.rciapplication_model_id, t_RciApplication_Model_id.mod_name, t_RciApplication_Model_id.mod_image, t.rci_app_dataflows_model_id, t_rciAppDataflowsModelId.mod_name, t.rci_app_dataflows_macro_model_id, t_rciAppDataflowsMacroModelId.mod_name, t.rci_app_flows_model_id, t_rciAppFlowsModelId.mod_name, t.rci_app_cmdb_techno, t.rci_app_euc_in_out, t.rci_app_euc_version, t.rci_app_contract_type, t.rci_app_comments, t.rci_app_cca_status, t.rci_app_cca_comments, t.rci_app_cca_controled_by, t.rci_app_cca_int_usr_auth_id, t_rciAppCcaIntUsrAuthId.rci_security_auth_name, t.rci_app_cca_int_rights, t.rci_app_cca_int_security_policy_id, t_rciAppCcaIntSecurityPolicyId.rci_sec_policy_name, t.rci_app_cca_ext_usr_auth_id, t_rciAppCcaExtUsrAuthId.rci_security_auth_name, t.rci_app_cca_ext_rights, t.rci_app_rsp_ent_id, t_rciAppRspEntId.rci_rsp_ent_name, t_rciAppRspEntId.rci_rsp_ent_cty_id, t_rciRspEntCtyId.cty_code2, t.rci_app_lei, t.rci_app_dc_op_site, t.rci_app_dc_recov_site, t.rci_app_retention_time, t.rci_app_euc, t.rci_app_backup_type, t.rci_app_drp_view, t.rci_app_funct_domains, t.rci_app_validation_status, t.rci_status_before_tbv, t.rci_status_updated_dt, t.rci_app_orgdom_id, t_rciAppOrgdomId.rci_org_dom_identifier, t_rciAppOrgdomId.rci_org_dom_name, t_rciAppOrgdomId.rci_org_dom_country_id, null, t.rci_app_principal_it_email, t.rci_wkf_completion, t.rci_app_rosier_id, t.rci_app_principal_it, t.rci_app_technical_id, t.rci_app_kpi_eligible, null, t.created_dt, t.created_by, t.updated_dt, t.updated_by from rci_application t left outer join rci_application t_rciAppOriginAppId on (t.rci_app_origin_app_id=t_rciAppOriginAppId.row_id) left outer join rci_application_type t_rciAppTypeId on (t.rci_app_type_id=t_rciAppTypeId.row_id) left outer join iso_country t_rciAppCtyId on (t.rci_app_cty_id=t_rciAppCtyId.row_id) left outer join iso_country_grouping t_rciAppCtyGrpId on (t.rci_app_cty_grp_id=t_rciAppCtyGrpId.row_id) left outer join m_user t_rciAppCmsiRit on (t.rci_app_cmsi_rit=t_rciAppCmsiRit.row_id) left outer join m_user t_rciAppCmsiRm on (t.rci_app_cmsi_rm=t_rciAppCmsiRm.row_id) left outer join m_model t_RciApplication_Model_id on (t.rciapplication_model_id=t_RciApplication_Model_id.row_id) left outer join m_model t_rciAppDataflowsModelId on (t.rci_app_dataflows_model_id=t_rciAppDataflowsModelId.row_id) left outer join m_model t_rciAppDataflowsMacroModelId on (t.rci_app_dataflows_macro_model_id=t_rciAppDataflowsMacroModelId.row_id) left outer join m_model t_rciAppFlowsModelId on (t.rci_app_flows_model_id=t_rciAppFlowsModelId.row_id) left outer join rci_security_auth t_rciAppCcaIntUsrAuthId on (t.rci_app_cca_int_usr_auth_id=t_rciAppCcaIntUsrAuthId.row_id) left outer join rci_security_policy t_rciAppCcaIntSecurityPolicyId on (t.rci_app_cca_int_security_policy_id=t_rciAppCcaIntSecurityPolicyId.row_id) left outer join rci_security_auth t_rciAppCcaExtUsrAuthId on (t.rci_app_cca_ext_usr_auth_id=t_rciAppCcaExtUsrAuthId.row_id) left outer join rci_responsible_entity t_rciAppRspEntId on (t.rci_app_rsp_ent_id=t_rciAppRspEntId.row_id) left outer join iso_country t_rciRspEntCtyId on (t_rciAppRspEntId.rci_rsp_ent_cty_id=t_rciRspEntCtyId.row_id) left outer join rci_org_domain t_rciAppOrgdomId on (t.rci_app_orgdom_id=t_rciAppOrgdomId.row_id) where (t.row_id=?) and ((t.rci_app_is_backup=? or t.rci_app_is_backup is null)) order by t.updated_dt desc, t_rciAppTypeId.rci_app_type_name asc, t.rci_app_name asc, t.row_id asc Hosts=[4073][0] 2024-11-18 13:34:18,593|SIMPLICITE|INFO||http://simplicite-dev-67bb8cd5f9-6ndrd:8080||SQLUSER|system|DBAccess|SQL|query|SQL=jdbc/simplicite: select t.row_id, t.rci_appsub_rrsg_processed, t.rci_appsub_app_id, t.rci_appsub_rrsg_country, t_rciAppsubAppId.rci_app_name, t_rciAppsubAppId.rci_app_corp, t_rciAppsubAppId.rci_app_technical_id, t_rciAppsubAppId.rci_app_version, t_rciAppsubAppId.rci_app_criticality, t_rciAppsubAppId.rci_app_state, t_rciAppsubAppId.rci_app_validation_status, t_rciAppsubAppId.rci_app_is_backup, t_rciAppsubAppId.rci_app_division, t_rciAppsubAppId.rci_app_identifier, t_rciAppsubAppId.rci_app_orgdom_id, t_rciAppsubAppId.rci_app_cty_id, t_rciAppCtyId.iso_cty_ctygrp_id, t_rciAppsubAppId.rci_app_cty_grp_id, t.rci_wkf_completion, t.rci_appsub_comments, t.rci_appsub_sub_id, t_rciAppsubSubId.rci_sub_name, t_rciAppsubSubId.rci_sub_scope, t_rciAppsubSubId.rci_sub_cou_id, t_rciSubCouId.cty_code2, t_rciSubCouId.iso_cty_ctygrp_id, t_isoCtyCtygrpId.iso_ctygrp_code, t.rci_appsub_record_status, t.rci_appsub_identifier, t.rci_appsub_rsp_ent_id, t_rciAppsubRspEntId.rci_rsp_ent_name, t_rciAppsubRspEntId.rci_rsp_ent_cty_id, t.rci_appsub_rrsg_resp_ent, t_rciRspEntCtyId.cty_code2, t_rciRspEntCtyId.cty_name, t.rci_appsub_lei, t.rci_appsub_functdom_id, t_rciAppsubFunctdomId.rci_drp_funct_dom_name, t.rci_appsub_technical_id, t.rci_appsub_dc_op_site, t.rci_appsub_dc_recov_site, t.rci_appsub_backup_type, t.rci_appsub_rrsg_bus_cmsi, t.rci_appsub_rrsg_bus_cmsi_email, t.rci_appsub_retention_time, t.rci_appsub_euc, t.rci_appsub_euc_in_out, t.rci_appsub_euc_version, t.rci_appsub_resp, t.rci_appsub_rrsg_it_cmsi, t.rci_appsub_rrsg_it_cmsi_email, t.rci_appsub_confidentiality, t.rci_appsub_drp_required, t.rci_appsub_ext_registry, t.rci_appsub_drp_view, t.rci_app_is_backup, t.rci_field_is_archived, t.rci_status_before_tbv, t.rci_status_updated_dt, t.rci_appsub_rosier_id, t.created_dt, t.created_by, t.updated_dt, t.updated_by from rci_app_sub t left outer join rci_application t_rciAppsubAppId on (t.rci_appsub_app_id=t_rciAppsubAppId.row_id) left outer join iso_country t_rciAppCtyId on (t_rciAppsubAppId.rci_app_cty_id=t_rciAppCtyId.row_id) left outer join rci_subsidiary t_rciAppsubSubId on (t.rci_appsub_sub_id=t_rciAppsubSubId.row_id) left outer join iso_country t_rciSubCouId on (t_rciAppsubSubId.rci_sub_cou_id=t_rciSubCouId.row_id) left outer join iso_country_grouping t_isoCtyCtygrpId on (t_rciSubCouId.iso_cty_ctygrp_id=t_isoCtyCtygrpId.row_id) left outer join rci_responsible_entity t_rciAppsubRspEntId on (t.rci_appsub_rsp_ent_id=t_rciAppsubRspEntId.row_id) left outer join iso_country t_rciRspEntCtyId on (t_rciAppsubRspEntId.rci_rsp_ent_cty_id=t_rciRspEntCtyId.row_id) left outer join rci_drp_funct_domain t_rciAppsubFunctdomId on (t.rci_appsub_functdom_id=t_rciAppsubFunctdomId.row_id) where (t.row_id=?) order by t.row_id asc Hosts=[3055] 2024-11-18 13:34:18,604|SIMPLICITE|INFO||http://simplicite-dev-67bb8cd5f9-6ndrd:8080||SQLUSER|system|DBAccess|SQL|query|SQL=jdbc/simplicite: select t.row_id, t.rci_app_bce_doms, t.rci_app_funct_doms, t.rci_updates_log, t.rci_app_version, t.rci_app_is_backup, t.rci_field_is_archived, t_rciAppOriginAppId.rci_app_technical_id, t.rci_app_origin_app_id, t_rciAppOriginAppId.rci_app_version, t.rci_app_identifier, t.rci_app_name, t.rci_app_long_name, t.rci_app_sia, t.rci_app_recordstatus, t.rci_app_level, t.rci_app_criticality, t.rci_app_outsourced, t.rci_app_mfs_criticality, t.rci_app_confidentiality, t.rci_app_drp, t.rci_app_state, t.updated_dt, t.rci_app_cmdb_updated, t.rci_app_cmdb_overwrite, t.rci_app_data_source, t.rci_app_description, t.rci_app_type, t.rci_app_type_id, t_rciAppTypeId.rci_app_type_name, t.rci_app_document_link, t.rci_app_group, t.rci_app_corp, t.rci_app_cty_id, t_rciAppCtyId.cty_code2, t_rciAppCtyId.iso_cty_ctygrp_id, t.rci_app_cty_grp_id, t_rciAppCtyGrpId.iso_ctygrp_code, null, t.rci_app_division, t.rci_app_tag, t.rci_app_copyid, t.rci_app_cmsi_rit, t_rciAppCmsiRit.rci_user_full_name, t_rciAppCmsiRit.usr_login, t.rci_app_cmsi_rm, t_rciAppCmsiRm.rci_user_full_name, t_rciAppCmsiRm.usr_login, t.rciapplication_model_id, t_RciApplication_Model_id.mod_name, t_RciApplication_Model_id.mod_image, t.rci_app_dataflows_model_id, t_rciAppDataflowsModelId.mod_name, t.rci_app_dataflows_macro_model_id, t_rciAppDataflowsMacroModelId.mod_name, t.rci_app_flows_model_id, t_rciAppFlowsModelId.mod_name, t.rci_app_cmdb_techno, t.rci_app_euc_in_out, t.rci_app_euc_version, t.rci_app_contract_type, t.rci_app_comments, t.rci_app_cca_status, t.rci_app_cca_comments, t.rci_app_cca_controled_by, t.rci_app_cca_int_usr_auth_id, t_rciAppCcaIntUsrAuthId.rci_security_auth_name, t.rci_app_cca_int_rights, t.rci_app_cca_int_security_policy_id, t_rciAppCcaIntSecurityPolicyId.rci_sec_policy_name, t.rci_app_cca_ext_usr_auth_id, t_rciAppCcaExtUsrAuthId.rci_security_auth_name, t.rci_app_cca_ext_rights, t.rci_app_rsp_ent_id, t_rciAppRspEntId.rci_rsp_ent_name, t_rciAppRspEntId.rci_rsp_ent_cty_id, t_rciRspEntCtyId.cty_code2, t.rci_app_lei, t.rci_app_dc_op_site, t.rci_app_dc_recov_site, t.rci_app_retention_time, t.rci_app_euc, t.rci_app_backup_type, t.rci_app_drp_view, t.rci_app_funct_domains, t.rci_app_validation_status, t.rci_status_before_tbv, t.rci_status_updated_dt, t.rci_app_orgdom_id, t_rciAppOrgdomId.rci_org_dom_identifier, t_rciAppOrgdomId.rci_org_dom_name, t_rciAppOrgdomId.rci_org_dom_country_id, null, t.rci_app_principal_it_email, t.rci_wkf_completion, t.rci_app_rosier_id, t.rci_app_principal_it, t.rci_app_technical_id, t.rci_app_kpi_eligible, null, t.created_dt, t.created_by, t.updated_dt, t.updated_by from rci_application t left outer join rci_application t_rciAppOriginAppId on (t.rci_app_origin_app_id=t_rciAppOriginAppId.row_id) left outer join rci_application_type t_rciAppTypeId on (t.rci_app_type_id=t_rciAppTypeId.row_id) left outer join iso_country t_rciAppCtyId on (t.rci_app_cty_id=t_rciAppCtyId.row_id) left outer join iso_country_grouping t_rciAppCtyGrpId on (t.rci_app_cty_grp_id=t_rciAppCtyGrpId.row_id) left outer join m_user t_rciAppCmsiRit on (t.rci_app_cmsi_rit=t_rciAppCmsiRit.row_id) left outer join m_user t_rciAppCmsiRm on (t.rci_app_cmsi_rm=t_rciAppCmsiRm.row_id) left outer join m_model t_RciApplication_Model_id on (t.rciapplication_model_id=t_RciApplication_Model_id.row_id) left outer join m_model t_rciAppDataflowsModelId on (t.rci_app_dataflows_model_id=t_rciAppDataflowsModelId.row_id) left outer join m_model t_rciAppDataflowsMacroModelId on (t.rci_app_dataflows_macro_model_id=t_rciAppDataflowsMacroModelId.row_id) left outer join m_model t_rciAppFlowsModelId on (t.rci_app_flows_model_id=t_rciAppFlowsModelId.row_id) left outer join rci_security_auth t_rciAppCcaIntUsrAuthId on (t.rci_app_cca_int_usr_auth_id=t_rciAppCcaIntUsrAuthId.row_id) left outer join rci_security_policy t_rciAppCcaIntSecurityPolicyId on (t.rci_app_cca_int_security_policy_id=t_rciAppCcaIntSecurityPolicyId.row_id) left outer join rci_security_auth t_rciAppCcaExtUsrAuthId on (t.rci_app_cca_ext_usr_auth_id=t_rciAppCcaExtUsrAuthId.row_id) left outer join rci_responsible_entity t_rciAppRspEntId on (t.rci_app_rsp_ent_id=t_rciAppRspEntId.row_id) left outer join iso_country t_rciRspEntCtyId on (t_rciAppRspEntId.rci_rsp_ent_cty_id=t_rciRspEntCtyId.row_id) left outer join rci_org_domain t_rciAppOrgdomId on (t.rci_app_orgdom_id=t_rciAppOrgdomId.row_id) where (t.row_id=?) and ((t.rci_app_is_backup=? or t.rci_app_is_backup is null)) order by t.updated_dt desc, t_rciAppTypeId.rci_app_type_name asc, t.rci_app_name asc, t.row_id asc Hosts=[4073][0] 2024-11-18 13:34:18,627|SIMPLICITE|INFO||http://simplicite-dev-67bb8cd5f9-6ndrd:8080||INFO|designer|com.simplicite.commons.RCIB.RciCommonObject|pauseCheckCompletion||Event: pauseCheckCompletion 2024-11-18 13:34:18,629|SIMPLICITE|INFO||http://simplicite-dev-67bb8cd5f9-6ndrd:8080||SQLUSER|system|DBAccess|SQL|query|SQL=select d.dbd_name, d.dbd_path, d.dbd_size, d.dbd_vers, d.dbd_mime, d.dbd_resp_id, d.dbd_index_id, o.obj_name, f.fld_name, d.dbd_row_id, d.updated_dt from m_document d left outer join m_object o on (d.dbd_object_id=o.row_id) left outer join m_field f on (d.dbd_field_id=f.row_id) where d.row_id=223469 Hosts= 2024-11-18 13:34:18,661|SIMPLICITE|INFO||http://simplicite-dev-67bb8cd5f9-6ndrd:8080||SQLUSER|system|DBAccess|SQL|query|SQL=select din_name from m_docindex where row_id=7 Hosts= 2024-11-18 13:34:18,662|SIMPLICITE|INFO||http://simplicite-dev-67bb8cd5f9-6ndrd:8080||SQLUSER|system|DBAccess|SQL|query|SQL=jdbc/simplicite: select t.row_id, t.rci_appsub_rspent_appsub_id, t_rciAppsubRspentAppsubId.rci_appsub_app_id, t_rciAppsubAppId.rci_app_name, t_rciAppsubRspentAppsubId.rci_appsub_sub_id, t_rciAppsubAppId.rci_app_technical_id, t_rciAppsubAppId.rci_app_version, t_rciAppsubSubId.rci_sub_cou_id, t_rciSubCouId.cty_name, t_rciSubCouId.cty_code2, t_rciSubCouId.iso_cty_ctygrp_id, t_isoCtyCtygrpId.iso_ctygrp_code, t.rci_appsub_rspent_rspent_id, t_rciAppsubRspentRspentId.rci_rsp_ent_name, t.rci_app_is_backup, t.rci_field_is_archived, t.created_dt, t.created_by, t.updated_dt, t.updated_by from rci_appsub_rspent t left outer join rci_app_sub t_rciAppsubRspentAppsubId on (t.rci_appsub_rspent_appsub_id=t_rciAppsubRspentAppsubId.row_id) left outer join rci_application t_rciAppsubAppId on (t_rciAppsubRspentAppsubId.rci_appsub_app_id=t_rciAppsubAppId.row_id) left outer join rci_subsidiary t_rciAppsubSubId on (t_rciAppsubRspentAppsubId.rci_appsub_sub_id=t_rciAppsubSubId.row_id) left outer join iso_country t_rciSubCouId on (t_rciAppsubSubId.rci_sub_cou_id=t_rciSubCouId.row_id) left outer join iso_country_grouping t_isoCtyCtygrpId on (t_rciSubCouId.iso_cty_ctygrp_id=t_isoCtyCtygrpId.row_id) left outer join rci_responsible_entity t_rciAppsubRspentRspentId on (t.rci_appsub_rspent_rspent_id=t_rciAppsubRspentRspentId.row_id) where (t.rci_appsub_rspent_appsub_id=?) order by t.row_id asc Hosts=[3055] 2024-11-18 13:34:18,665|SIMPLICITE|INFO||http://simplicite-dev-67bb8cd5f9-6ndrd:8080||INFO|designer|com.simplicite.objects.RCIB.RciAppSub|validate2 : ||Event: ERR_ENUM:Status#ERROR#rciAppsubRecordStatus row_id 3055 instance tmp_ajax_RciAppSub 2024-11-18 13:34:18,666|SIMPLICITE|INFO||http://simplicite-dev-67bb8cd5f9-6ndrd:8080||INFO|designer|com.simplicite.objects.RCIB.RciApplication|askOrCancelValidationScopes||Event: AEK askOrCancelValidationScopes res = [ERR_ENUM:Status#ERROR#rciAppsubRecordStatus] 2024-11-18 13:34:18,666|SIMPLICITE|INFO||http://simplicite-dev-67bb8cd5f9-6ndrd:8080||INFO|designer|com.simplicite.objects.RCIB.RciApplication|askOrCancelValidation||Event: EFE askOrCancelValidation 20 2024-11-18 13:34:18,666|SIMPLICITE|INFO||http://simplicite-dev-67bb8cd5f9-6ndrd:8080||INFO|designer|com.simplicite.objects.RCIB.RciApplication|askOrCancelValidation||Event: AEK askOrCancelValidation/askOrCancelValidationScopes res = [ERR_ENUM:Status#ERROR#rciAppsubRecordStatus] 2024-11-18 13:34:18,666|SIMPLICITE|INFO||http://simplicite-dev-67bb8cd5f9-6ndrd:8080||INFO|designer|com.simplicite.objects.RCIB.RciApplication|askForValidation||Event: AEK askOrCancelValidation res = [ERR_ENUM:Status#ERROR#rciAppsubRecordStatus]

Je pige pas tout :wink: mais je vois deux choses :

Ici, le status est setté sans faire de select ou de setValues préalable = donc sur le tuple courant qui n’a pas forcément les bons “états suivants”, en moyenne ça doit marcher puisqu’on vient tout juste du formulaire mais si l’état a changé ou dans des cas plus rares où d’autres choses seraient modifiés en mémoire, pas sûr que les états suivants soient encore les bons vis-à-vis de l’état en base = ERR_ENUM

Il faudrait forcer un select(getRowId()) juste avant de setter le statut + validate + save, pour être sur d’avoir chargé les bons états en mémoire.

De façon générale, on fait toujours un select/setValues avant de faire des setValue + save au sein d’un block synchronized (obj.getLock()) de l’instance pour éviter toute concurrence d’accès, qq chose comme :

synchronized (getLock()) {
// actualise les données en mémoires et surtout les ENUM possibles en fonction de l'état courant
  if (select(getRowId())) { 
    setFieldValue("rciAppRecordstatus",val);
    List<String> res = this.validate(); // pas besoin du "new Array" précédent
    ... save
  }
}

et autre truc à vérifier :

Si BLOCAGE_ENV est mal positionné on peut perdre des boutons d’action. Je n’ai pas vu où ce flag est positionné.

Merci, j’ai modifié la partie setFieldValue, mais vu que ce n’est pas sur cet objet que j’ai l’erreur mais sur RciAppSub, je ne sais pas si c’est bien la cause.

La variable BLOCAGE_ENV est un param système donc ça ne peut pas venir de là.

As-tu une idée d’où je pourrais mettre des traces pour en savoir plus ?

De ce que je comprends des logs c’est bien askOrCancelValidationScopes qui retourne une erreur ERR_ENUM.

Que fait com.simplicite.objects.RCIB.RciAppSub|validate2 ?
puis com.simplicite.objects.RCIB.RciApplication|askOrCancelValidationScopes qui ne faisait pas de select avant de modifier le record.

Il y a bien un lien entre les 2 objets niveau code pour générer ces traces au même moment.

L’objet est modifié et laissé dans un état impropre, seul un “re-select” le remet au carré en mémoire vis-à-vis de la base = data + state-model + linked lists + documents…

Je pense que le select ajouté suffira à ne plus retourner d’erreur (si la transition du setValue est bien valide).

AEK = Abed ?

Oui c’est bien askOrCancelValidationScopes qui retourne l’erreur mais on a bien un select sur RciAppSub (d’ailleurs je vois dans Network qu’on fait un get sur l’objet et que les transitions retournées sont vides)

Le select manquant était sur askOrCancelValidationApp

Le validate2 est dans le validate du CommonObject (classe partagée par tous les objets métiers)

@Override	
	public List<String> validate(boolean onlyErrors)
	{	
		//AppLog.info(getClass(), "Entering validate for " + getName() + "rowid " + getRowId(), null, getGrant());

		List<String> msgs = super.validate(onlyErrors);
		
		if (msgs != null && msgs.size() == 1 && isArchivable())
			{
					String msg = msgs.get(0);
		AppLog.info(getClass(), "validate2 : ", msg + " row_id " + getRowId() + " instance " + getInstanceName(), getGrant());
			}

		if (!isCreateBackup() && !isBatchInstance() && getGrant().getParameter("MIGRATION_MODE").equals("0"))
		{
	
			//Cas où on aurait un élément archivé isolé - ne devrait pas arriver
			if (msgs != null && msgs.size() == 1 && isArchivable())
			{
					String msg = msgs.get(0);
					if (Message.getCode(msg).equals("ERR_USERKEY"))
					{
						ObjectDB obj = getGrant().getTmpObject(getName());
						obj.resetFilters();
						
						for ( ObjectField keyField : this.getFunctId())	
						{
	
							if (!keyField.getValue().isEmpty() && keyField.getRefFieldName() == null)
							{
								obj.getField(keyField.getName()).setFilter(getFieldValue(keyField.getName()));
							}
						}
						
						obj.setFieldFilter("rciFieldIsArchived", true);
						
						List<String[]> dupObjList = obj.search();
						
						if (dupObjList.size() > 0)
						{AppLog.info(getClass(), "validate2", getRowId(), getGrant());
	
							obj.resetValues();
							obj.resetFilters();
							obj.select(dupObjList.get(0)[0]);
							obj.delete();
							
							return null;
						}
						
						
					}
	
			}
		}
		
		return msgs;
	}

Je n’ai pas la capacité à reprendre tout votre code.
Si les transitions sont vides en front c’est que l’état en cours n’a plus d’états suivants (i.e. nb ENUM actifs < 2 en back = le premier étant l’état courant, il en faut au moins 2 pour avoir une transition).

Il faut juste respecter les bonnes pratiques et toujours se demander si l’objet est dans le bon contexte avant de le modifier.

  • if (select) { delete or update } = on modifie s’il existe encore avec des données à jour, j’ai vu un delete sans “if” select… sinon on va supprimer un autre record (dans le row_id courant en mémoire si le select ne ramène rien)…
  • synchronized si mutli-threadé (notement les instances tmp utilisées par cron ou UI…)

Ajoute des logs

  • sur la valeur du statut et des ENUM actifs en mémoire status.getList().getItems()
  • sur le contenu de toutes les transitions connues/habilitées status.getStateModel().

Il doit y avoir un endroit qui met l’objet dans un état invalide sans le recharger.

L’action en front :

  • fait un save préalable (quels statuts en entrée preValidate/sortie postSave back ? quels sont les ENUM actifs ?)
  • appelle le callback de l’action (idem statuts entrée/sortie ?)
  • puis réaffiche le formulaire (getForUpdate = et paf plus de transitions !)

Je viens de reproduire le problème, je ne sais toujours pas comment mais je n’ai pas utilisé l’action avant que ça arrive.

Les transitions d’état ont disparu sur toutes les instances de RciAppSub, pour tous les user, quelle que soit la valeur du statut de l’instance.

Si je fais un CC les transitions en liste vont réapparaître.

J’avais mis la trace que tu m’as conseillée, quand j’appelle l’action j’ai ceci pour un RciAppSub au statut To be reviewed

image

[EDIT] Les transitions ont aussi disparu sur mon objet RciApplication

Très étrange,
Dans la log copiée, on voit qu’il n’y a plus qu’un seul état dans l’ENUM ? ce qui signifie qu’il n’y a plus de transitions habilitées (en mémoire) pour le user si le “select” a bien été fait.

Si tout disparait partout et pour tous les users, il y a plutôt un pb de perte des transitions dans la définition du champ status dans le core-cache (qui sert à cloner les instances d’objet par session), et pas juste un problème de remettre les ENUM en fonction de l’état courant.

Il faudrait regarder ce que contient List<FieldStateTransition> list = status.getStateModel()
Si c’est vide de temps en temps, il faut trouver pourquoi.

  • Faites vous des mises à jour de contenu de liste de valeurs à la volée par code, ou des changement de responsabilités des transitions… enfin qq chose qui change une définition de “design” à la volée ?
  • Ou des créations/suppressions de groupes liés à des droits sur ces objets/status par profil ou autre ?

Il y a peut être un clear-cache partiel sur les objets métier qui ne remonte plus les transitions en cache.

Si c’est non vide, et que les transitions ont bien des habilitations (FieldStateTransition.getGroups() non vide)

  • c’est plutôt un pb de code, par exemple au niveau du hook isStateTransitionEnable qui se mettrait à envoyer toujours false

Je vais essayer de voir ce qui pourrait perdre les transitions ou leurs droits, mais sans modop c’est compliqué.

Oui c’est bien ça, la trace boucle sur les états donc on n’en a qu’un.

appsub.select(scope[i]);
			    
			    for (EnumItem statusItem : appsub.getStatusField().getList().getItems())
			    {
			    	AppLog.info(" Item " + statusItem.getValue(), getGrant());
			    }
			    
				String val = (act.equals("ASK")) ? RECORDSTATUS_TOBEVALIDATED : appsub.getFieldValue("rciStatusBeforeTbv");
			    appsub.setFieldValue("rciAppsubRecordStatus",val);

C’est très énervant car j’ai essayé ce matin de reproduire dans tous les sens en vain, et ça m’est arrivé une heure plus tard en faisant complètement autre chose.

Rien n’est fait dynamiquement sur la LOV ni sur les droits.
Par contre c’est vrai que j’ai fait du code un peu hasardeux pour gérer mes trois objets en une fois dans la classe mère, donc j’instancie beaucoup de tmp_object. J’ai mis des traces vraiment partout cette fois, je reviendrai avec les infos quand ça se reproduira.

Il y a le GC de Simplicité qui dégage les instances d’objet inutilisées de la session (après 30min), mais ça ne dégage pas la définition de l’objet du core-cache. Si tu étais en DEV en train de faire du design, c’est possible qu’un clear-cache partiel ait rendu instable certains objets, il faut souvent vider tous les caches quand les choses sont trop imbriquées.

Il faut aussi debugger appsub.getStatusField().getStateModel() s’il est vide (ou transitions sans groupe ce qui m’étonnerait).

try {
  if (Tool.isEmpty(appsub.getStatusField().getStateModel()))
    throw new Exception();
} catch (Exception e) { // force une exception pour récupérer la stack java
    AppLog.error("EMPTY TRANSITION appsub", e, getGrant());
}

Suite à relecture de Simplicité rien de suspect, le clonage d’un attribut ne clone pas le state-model mais c’est normal il est calculé plus tard, on peut renforcer cette partie au cas où mais j’y crois pas trop.

Autre piste :

La liste de valeurs et les transitions qui montent en mémoire dépendent de la langue de l’utilisateur. Est-ce que quelque chose fait changer la langue FRA/ENU par autre chose ?

Si tel est la cas, il se pourrait qu’aucune transition ne remonte du core-cache au moment où on instancie un objet via :

List<FieldStateTransition> fst = 
CoreCache.getInstance().getTransitions(grant.getLang(), "LIST_NAME");

Je viens de reproduire de nouveau et avec les traces j’ai ciblé où ça se passe et trouvé ça dans mon code :frowning:

app.select("rciAccAppId");

J’imagine que c’est possible qu’ensuite les instances en cache fassent n’importe quoi ?

[EDIT] J’ai de nouveau le problème après correction :frowning:

Un select en erreur ne changera pas le core-cache ni les transitions pré-définies, ni toutes les sessions utilisateurs. Là le select ne ramènera rien donc va savoir ce que fera le code qui suit,
les états suivants en mémoire sont surement vidés de cette instance, ou retour à l’état inital.

D’où l’importance de toujours faire un if (app.select(x)) ....

  • si le tuple n’existe plus en base
  • si search-spec qui interdit l’accès
  • et si x est incorrect…

Mais bon, si on refait un select sur un vrai row_id (par code ou open form UI…), tout devrait revenir à la normal tant que les transitions sont définies en core-cache et clonées dans le champ status lui-même (cf plus haut getStateModel).

Je vais du coup faire le tour de tous les select pour corriger.

J’ai l’impression que ça se reproduit quand je reviens après un moment d’inactivité, mais difficile d’être sûre.
En attendant, dans la trace, j’ai bien les groupes de droits vides.

2024-11-20 16:14:02,891|SIMPLICITE|ERROR||http://simplicite-dev-67bb8cd5f9-6ndrd:8080||ERROR|system|com.simplicite.util.ObjectHooks|postSave||Event: Implementation error in the postSave hook of object RciAppSub java.lang.NullPointerException: Cannot invoke "java.util.List.size()" because the return value of "com.simplicite.util.FieldStateTransition.getGroups()" is null at com.simplicite.commons.RCIB.RciWorkflowObject.postSave(RciWorkflowObject.java:383) at com.simplicite.objects.RCIB.RciAppSub.postSave(RciAppSub.java:361) at com.simplicite.util.ObjectHooks.postSave(ObjectHooks.java:701) at com.simplicite.util.engine.ObjectManager.save(ObjectManager.java:3519) at com.simplicite.util.engine.ObjectDirect.save(ObjectDirect.java:480) at com.simplicite.util.ObjectDB.save(ObjectDB.java:1408) at com.simplicite.objects.RCIB.RciAppSub.updateCorrespondents(RciAppSub.java:536) at com.simplicite.objects.RCIB.RciAccountableAppsub.updateScopes(RciAccountableAppsub.java:418) at com.simplicite.objects.RCIB.RciAccountableAppsub.postUpdate(RciAccountableAppsub.java:389) at com.simplicite.util.ObjectHooks.postUpdate(ObjectHooks.java:665) at com.simplicite.util.engine.ObjectManager.update(ObjectManager.java:3044) at com.simplicite.util.engine.ObjectDirect.update(ObjectDirect.java:437) at com.simplicite.util.ObjectDB.update(ObjectDB.java:1365) at com.simplicite.util.engine.ObjectManager.save(ObjectManager.java:3512) at com.simplicite.util.engine.ObjectDirect.save(ObjectDirect.java:480) at com.simplicite.util.ObjectDB.save(ObjectDB.java:1408) at com.simplicite.webapp.tools.JSONServletTool.update(JSONServletTool.java:1276) at com.simplicite.webapp.ObjectJson.update(ObjectJson.java:649) at com.simplicite.webapp.tools.JSONServletTool.businessObjectService(JSONServletTool.java:634) at com.simplicite.webapp.servlets.AbstractJSONServlet.process(AbstractJSONServlet.java:168) at com.simplicite.webapp.servlets.AbstractJSONServlet.service(AbstractJSONServlet.java:127) at javax.servlet.http.HttpServlet.service(HttpServlet.java:623) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:199) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:168) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144) at com.simplicite.webapp.filters.RewriteFilter.doFilter(RewriteFilter.java:68) at com.simplicite.webapp.filters.AbstractFilter.doFilter(AbstractFilter.java:49) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:168) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144) at com.simplicite.webapp.filters.HTTPHeadersFilter.doFilter(HTTPHeadersFilter.java:39) at com.simplicite.webapp.filters.AbstractFilter.doFilter(AbstractFilter.java:49) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:168) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144) at com.simplicite.webapp.filters.AuthMethodFilter.doFilter(AuthMethodFilter.java:222) at com.simplicite.webapp.filters.AbstractFilter.doFilter(AbstractFilter.java:49) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:168) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:156) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:660) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:346) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:383) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:937) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1791) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190) at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) at java.base/java.lang.Thread.run(Thread.java:840)

Ca se précise…
Oui ce n’est pas normal qu’une transition n’ait plus de groupe. et ça explique pourquoi il n’y ait plus de transition en front.

  • es tu seule sur ton application ? que font les autres ?
  • quid de ma question sur la langue de l’utilisateur qui changerait en cours de route (setLang temporaire par code ou tu changes de langue…) ?
  • peux tu tracer ce que contient CoreCache.getInstance().getTransitions(grant.getLang(), "LIST_NAME") quand ça plante ? LIST_NAME = le nom de l’enum du statut.

je suspecte que la langue serait fausse au moment de (re)charger l’objet dans le core-cache.

L’instance d’objet a surement été dégagé de ta session, il est recloné en session depuis le core-cache quand tu y reviens, comme après un logon. Tu peux arrêter temporairement les cron ObjectDynGC et ObjectFullGC pour voir si ça vient de là.