Filtrer une colonne avec valeurs calculées non persistantes

Bonsoir,

Je rencontre actuellement un problème pour effectuer un tri sur une colonne (dans une liste) dont les valeurs diffères en fonction de l’utilisateur.

Je m’explique : j’utilise le hook postSearch pour affecter des valeurs dans la colonne d’une liste. Jusqu’à présent aucun problème, les valeurs change bien en fonction de l’utilisateur.

Par contre impossible d’effectuer un tri dans les paramètres (aucun effet visible), et le click à coté de l’attribut dans la liste ne modifie pas l’ordre.

Y a-t-il un moyen pour parvenir à trier la liste ?

Merci d’avance,

Benoît

De manière générale lors de vos demandes de support merci de nous indiquer systématiquement votre version/patchlevel/revision (i.e. le resultat du /health).

Pouvez vous nous copier/coller le code de votre postSearch pour qu’on comprenne ce que vous y faites ? Si vous y valorisez des attributs c’est à vous de vous charger du (re)tri s’il porte sur cet attribut non géré par la plateforme (car le tri générique est effectué avant qu’il soit valorisé dans votre postSearch)

@Override
public List<String[]> postSearch(List<String[]> rows) {
	List<String> ssePerim = Arrays.asList(getGrant().getParameter("PERIMETRE_SSE").split("\\s*,\\s*"));
	int fieldSSE_row_id = this.getFieldIndex("row_id");
	int fieldSSE_DROITS = this.getFieldIndex("SSE_DROITS");
	List<String[]> rowsTri1 = new ArrayList<String[]>();
	List<String[]> rowsTri0 = new ArrayList<String[]>();
	for (int i = 0; i < rows.size(); i++) {
		String[] row = rows.get(i);
		if (ssePerim.contains(row[fieldSSE_row_id]) || getGrant().getParameter("PERIMETRE_SSE").equals("vide")) {
			row[fieldSSE_DROITS] = "1";
			rowsTri1.add(row);
		} else {
			row[fieldSSE_DROITS] = "0";
			rowsTri0.add(row);
		}
	}
	rowsTri1.addAll(rowsTri0);
	return rowsTri1;
}

Le tri que j’essaye de faire avant le return n’est pas pris en compte lorsque j’affiche la liste, peut être faut il trier ailleurs ?

Je ne vois pas de tri dans votre code…

Dans le postSearch la liste rows que vous recevez est déjà triée (la plateforme a effectuée une requête en base avec des order by utilisant les critères de tri par défaut de la définit de votre objet et/ou les critères de tri explicitement valorisés par l’utilisateur)

Si vous ajoutez un attribut (sont les valeurs étaient vides avant le postSearch et qui étaient donc “neutre” sur le tri) vous devez refaire le tri sur en tenant compte de ce critère supplémentaire (si celui-ci est bien positionné comme critère de tri, et si oui, en tenant compte de son ordre dans tri, le résultat n’est pas le même si c’est le 1er critère de tri, le dernier, ou au milieu).

Je vais regarder s’il existe une API Java niveau ObjectDB pour faire ce type de “post-tri”, j’en doute. Sinon il faudra que vous implémentiez votre propre méthode de “sort” adaptée à votre besoin

Pardon j’avais mal lu votre code, je vois que vous forcez un “tri” inconditionnel basé sur votre attribut dynamique.

Par “inconditionnel” je veux dire que vous ne tenez pas compte d’un éventuel ordre de tri positionné sur cet attribut, tel que votre code est écrit il devient donc, de fait, le 1er critère de tri.

Donc forcément ce critère n’est pas à la main de l’utilisateur. Pour qu’il le soit il faut écrire un code de tri moins inconditionnel.

Merci pour votre réponse David. Quel type de méthode peux permettre de rendre le tri moins inconditionnel ? Un “sort” ? Faut il que je tri dans le postSearch ou ailleurs ?

C’est ce que je disais dans ma reponse précédente: je vais regarder s’il existe une API Simplicité pour faire ce genre de “post-tri” ou “re-tri” en respectant l’ensemble des critères de tri mais je doute qu’une telle API existe car Simplicité repose sur les systèmes sous jacents (i.e. en général une base de données) pour effectuer le tri.

NB: un tel “post-tri” ne gérera pas la pagination = ce ne sera en fait qu’un “sur-tri” au sein de la liste de la page courante, donc ça ne se comportera jamais comme un “vrai” tri effectué par la base de données

Bonjour,

Il n’y a pas de re-tri dans la couche java, et ce n’est pas une bonne approche en terme de perf, il vaut mieux utiliser les mécanismes de la base prévus pour.

Le tri est fait au niveau SQL “order by” uniquement, donc votre champ doit nécessairement être persistant (avoir un nom physique) et donc calculé au preSave (1 seule fois), plutôt que d’essayer de le calculer à chaque search + refaire un tri au mieux en o(n*log(n)).

De ce que je comprends c’est un attribut non persistant qui se valorise dynamiquement en fct des rattachements du user à d’autres données métier (genre 1 si c’est un record qui me concerne 0 s’il ne me concerne pas)

C’est ça ?

C’est bien cela @david

Ok si ça dépend des droits il faut bien le calculer tout le temps.

  • Par contre pour activer le tri sur ce champ et la UI, je pense qu’il faut lui donner un champ physique (même s’il restera à vide si non alimenté au save, il le faut pour que le order by niveau SQL passe, et que la UI propose le click en colonne).
  • Dans votre code il faut récupérer l’ordre ou le filtre via field.getOrder() / getFilter(), si ordre négatif c’est rowsTri0 et rowsTri1 qui doivent s’inverser, si filtre=0 ou 1 ne renvoyer que rowsTri0 ou rowsTri1, etc.

et sinon getGrant().getParameter(“PERIMETRE_SSE”).equals(“vide”)
est factorisable dans votre boucle (il faut tout faire pour ne pas y passer trop de temps).

Ok je vais tester cela, merci pour vos réponses messieurs.