initRefSelect avec un parent dans un autre module

Tags: #<Tag:0x00007f2f31f789a8>

Bonjour,

J’ai un objet BCSIPerson qui est dans un module A.
J’ai un objet BCSIEAPMApp qui est dans un module B et qui a une FK vers BCSIPerson.

Donc on a module B qui dépend de module A.
Sur la FK, on veut ajouter un filtre sur le type de personne.
Cela est possible en passant par le hook initRefSelect de BCSIPerson.

Ce qui m’embête c’est que du coup, dans le module A, on obtient :

	@Override
	public void initRefSelect(ObjectDB parent) {
		String addSearchSpec = "";
	
		if ( null != parent ) {
			String parentName = parent.getName();
			
			
			if (parentName.equals("BCSIEAPMApp")) {
				addSearchSpec = "pers_type = 'DL'" ;
			}
		}
		
		if ( !"".equals(addSearchSpec) ) {
			AppLog.info(getClass(), "initRefSelect", "ADD this.getSearchSpec=<br/>" + "(" + this.getSearchSpec() + ") AND (" + addSearchSpec + ")", getGrant());
			this.setSearchSpec("(" + this.getSearchSpec() + ") AND (" + addSearchSpec + ")");
		}
	}

On a alors des références à un objet du module B dans le code d’un objet A. Hors nous souhaiterions que le module A soit totalement indépendant des autres puisqu’il s’agit d’un package d’éléments coummuns.
Savez-vous s’il y a un moyen/hook dans l’objet BCSIEAPMApp qui pourrait faire l’équivalent de ce code ?
Nous souhaiterions ainsi que notre module A ne contienne pas de références à des objets d’un autre package.

Cordialement
Amandine TRIDOU

[Platform]
Status=OK
Version=4.0.P24
BuiltOn=2020-09-08 13:58 (revision cc3e1c0a38d7b0549d655541696b9efd34201031)
Encoding=UTF-8
EndpointIP=21.0.9.2
EndpointURL=http://e55490efd12d:8080
TimeZone=Europe/Paris
SystemDate=2020-09-10 14:48:34

Ce n’est pas possible et en terme de maintenance ce n’est pas optimum. mais la dépendance reste textuelle (on teste un nom d’objet) et non pas une classe qui ne serait pas là.

On peut envisager de migrer ce hook pour l’exécuter de l’autre côté (en créant un autre hook pour compatibilité ascendante). On va regarder si c’est envisageable. Je passe le post en change request pour étudier le point.

Comme en Java ou tout modèle relationnel, on peut avoir ce genre de problème de dépendances déclaratives :

  • Référence par nom (et pas par classe) : sur toute librairie commune comme le GrantHooks qui est unique sur la plateforme pour toutes les applications, il parle de groupes et de menus accessibles qui n’y sont pas forcement déclarées : là il faudrait un GrantHooks par module qui viendrait se concaténer au global.

  • Ou des références croisées : si vous avez un cycle ou des références dans les 2 sens (APP référence une Person chef de projet, et une Personne qui aurait une APP préférée)

Dans ce dernier cas, il faut mettre les 2 objets dans le même module (si vous avez paramétré les dépendances de module une des références ne pourra pas être créée). Sinon il faudra importer vos 2 modules sans dépendance en 3 bandes (importer A, puis B, et re-A pour finir le cycle).

Pour mettre le code de l’autre côté, l’objet APP pourrait pré-instancier l’objet “ref_ajax_BCSIPerson” et lui mettre une search-spec au moment du initUpdate de l’application.

Mais il faudra penser à désarmer ce filtre sur tous les autres objets qui l’utilisent, dans les autres modules. Bref en terme de maintenance, c’est pas forcement mieux, avoir un seul initRefSelect permet de centraliser les if/else… au niveau de l’objet que cela concerne = le filtrage des personnes se fait dans l’objet Personne (et pas un peu partout).

De plus votre code ne retire jamais la searchSpec si on est passé par une App en premier, et qu’on passerait par un autre objet référençant une personne (erreur SQL pers_type unknown).

Merci pour votre retour.
Heureusement pour nous, nous avons pas rencontré le cas évoqué avec la persistance du searchSpec. Je surveillerai ce point.
EN vue d’améliorer la qualité de notre code, je pense que je vais crée un objet héritier à BCSIPerson qui lui sera dans le module B.

Je souhaiterai, toutefois (si vous avez le temps bien sûr) voir s’il y a une possibilité d’avoir un hook qui ne s’exécute que lors d’une recherche depuis un élément parent. Par Exemple dans notre cas lorsque l’utilisateur sélectionne un DL. Ce hook permettrait de compléter un searchspec.

Merci d’avance

Oui l’héritage est aussi une bonne option dans ce cas :
vous pouvez créer un objet PersonDL hérité de Person avec un filtre en dur (filtre : t.pers_type=‘DL’), et le mapper avec votre foreign-key de votre objet APP.

L’avantage est de ne pas avoir de code à faire donc sans aucun code à faire, sauf en cas de navigation, si vous souhaitez revenir vers l’objet Person, vous devrez utiliser le getTargetObject dans PersonDL pour rediriger vers Person.

mais bon si PersonDL hérite des hooks de Person, ce n’est pas nécéssaire.